请注意 SwiftyInsta 已不再积极维护。
更多信息请参考 #244。
如果你正在寻找更新替代方案,请查看 Swiftagram。
Instagram 为开发者提供了两种 API。Instagram API 平台(功能极其有限,且即将被停用),以及仅限 商业 和 创作者 账户使用的 Instagram Graph API。
然而,Instagram 应用本身依赖第三种类型的 API,即所谓的 私有 API 或 非官方 API,而 SwiftyInsta 是它们的 iOS、macOS、tvOS 和 watchOS 客户端,完全用 Swift 编写。 你可以尝试为用户创造更好的 Instagram 体验,或者编写用于自动化不同任务的机器人。
这些 私有 API 不需要 令牌 或 应用注册,但 Instagram 并未 授权 其外部使用。 使用风险自负。
File/Swift Packages/Add Package Dependency…。https://github.com/TheM4hd1/SwiftyInsta.git。CocoaPods 是 Cocoa 项目的依赖管理器。你可以使用以下命令安装它:
$ gem install cocoapods
要通过 CocoaPods 将 SwiftyInsta 集成到你的 Xcode 项目中,请在 Podfile 中指定它:
use_frameworks!
target '<Your Target Name>' do
pod 'SwiftyInsta', '~> 2.0'
end
然后运行以下命令:
$ pod install
SwiftyInsta 依赖于 CryptoSwift 和 keychain-swift。
Credentials// 这些需要是强引用。
self.credentials = Credentials(username: /* username */, password: /* password */, verifyBy: .text)
self.handler = APIHandler()
handler.authenticate(with: .user(credentials)) {
switch $0 {
case .success(let response, _):
print("登录成功。")
// 将缓存安全地持久化到钥匙串中,以便将来再次登录。
guard let key = response.persist() else { return print("无法持久化 `Authentication.Response`。") }
// 将 `key` 存储在你想要的任何位置,以便以后访问 `Authentication.Response`。
// `UserDefaults` 只是一个示例。
UserDefaults.standard.set(key, forKey: "current.account")
UserDefaults.standard.synchronize()
case .failure(let error):
if error.requiresInstagramCode {
/* 更新界面以请求代码 */
} else {
/* 通知用户 */
}
}
}
一旦用户输入了双重认证验证码或挑战码,只需执行以下操作:
self.credentials.code = /* the code */
而先前 authenticate(with: completionHandler:) 中的 completionHandler 将自动捕获响应。
LoginWebViewControllerlet login = LoginWebViewController { controller, result in
controller.dismiss(animated: true, completion: nil)
// 处理认证响应。
guard let (response, _) = try? result.get() else { return print("登录失败。") }
print("登录成功。")
// 将缓存安全地持久化到钥匙串中,以便将来再次登录。
guard let key = response.persist() else { return print("无法持久化 `Authentication.Response`。") }
// 将 `key` 存储在你想要的任何位置,以便以后访问 `Authentication.Response`。
// `UserDefaults` 只是一个示例。
UserDefaults.standard.set(key, forKey: "current.account")
UserDefaults.standard.synchronize()
}
if #available(iOS 13, *) {
present(login, animated: true, completion: nil) // 只需向下滑动即可关闭。
} else {
present(UINavigationController(rootViewController: login), // 已添加一个“取消”按钮以关闭它。
animated: true,
completion: nil)
}
或者使用 LoginWebView 实现你自己的自定义 UIViewController,然后通过 .webView(/* your login web view */) 将其传递给 APIHandler 的 authenticate 方法。
Authentication.Response如果你已经持久化了用户的 Authentication.Response:
// 恢复由 `Authentication.Response.persist()` 返回的 `key`。
// 在我们的示例中,我们将其存储在 `UserDefaults` 中。
guard let key = UserDefaults.standard.string(forKey: "current.account") else { return print("未找到 `key`。") }
// 恢复安全持久化的 `Authentication.Response`。
guard let cache = Authentication.Response.persisted(with: key) else { return print("未找到 `Authentication.Response`。") }
// 登录。
let handler = APIHandler()
handler.authenticate(with: .cache(cache)) { _ in
/* 在这里执行某些操作 */
}
所有端点都可以通过 APIHandler 实例轻松访问。
let handler: APIHandler = /* 一个有效、已认证的处理器 */
// 例如,你可以……
// …获取收件箱。
handler.messages.inbox(with: .init(maxPagesToLoad: .max),
updateHandler: nil,
completionHandler: { _, _ in /* 执行某些操作 */ })
// …获取所有关注者。
handler.users.following(user: .me,
with: .init(maxPagesToLoad: .max),
updateHandler: nil,
completionHandler: { _, _ in /* 执行某些操作 */ })
此外,响应现在会显示 API 返回的 JSON 文件中包含的每个值:只需访问任意 ParsedResponse 的 rawResponse 并开始浏览,或者使用推荐的附属属性(例如 User 的 username、name 等,以及 Media 的 aspectRatio、takenAt、content 等)。
欢迎提交 拉取请求 和 问题。
1.* 维护者2.* 维护者我们正在积极寻找维护者。
更多信息请参考 #244。
SwiftyInsta 采用 MIT 许可证。更多信息请参见 LICENSE。