使用 Swift 访问 Twitter
Access Twitter using Swift
我正在使用 Swifter 库在我的 Swift iOS 8 应用程序中访问 Twitter:https://github.com/mattdonnelly/Swifter。问题是我从 Twitter 收到 401 未授权错误。我仔细检查了任何可能的原因:
- 消费者key/secret错了
- 确保不要使用 API v1(使用 1.1)
这两个问题都已解决(根据 Twitter 文档),我仍然面临这个问题。我认为这与我的身份验证方式有关。我正在尝试在不使用设备上的 ACAccount 的情况下访问 public 提要。
这是我的代码:
// MARK: Twitter
var swifter: Swifter
required init(coder aDecoder: NSCoder) {
self.swifter = Swifter(consumerKey: "KEY", consumerSecret: "SECRET")
super.init(coder: aDecoder)
}
func getTwitterTimeline() {
let failureHandler: ((NSError) -> Void) = {
error in
self.alertWithTitle("Error", message: error.localizedDescription)
}
self.swifter.getStatusesUserTimelineWithUserID("erhsannounce", count: 20, sinceID: nil, maxID: nil, trimUser: true, contributorDetails: false, includeEntities: true, success: {
(statuses: [JSONValue]?) in
if statuses != nil {
self.tweets = statuses!
}
}, failure: failureHandler)
}
func alertWithTitle(title: String, message: String) {
var alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
更新: 我一直在开发该应用程序,试图实现仅使用应用程序(而非基于用户)的身份验证和访问令牌来读取 public 时间线.
我更新了代码以使用访问令牌和仅应用程序身份验证。不过还是不行。
required init(coder aDecoder: NSCoder) {
let accessToken = SwifterCredential.OAuthAccessToken(key: "KEY", secret: "SECRET")
let credential = SwifterCredential(accessToken: accessToken)
self.swifter = Swifter(consumerKey: "cKEY", consumerSecret: "cSECRET", appOnly: true)
swifter.client.credential = credential
super.init(coder: aDecoder)
}
2015 年 2 月 3 日更新
您需要使用“仅限应用程序身份验证”而不是传入 OAuth 令牌来对服务器进行身份验证。
除此之外,您在传递用户的屏幕名称时也没有正确请求带有 userId 的状态。需要用用户名获取用户id,然后请求status'。
完整的工作代码如下:
required init(coder aDecoder: NSCoder) {
self.swifter = Swifter(consumerKey: "cKEY", consumerSecret: "cSECRET", appOnly: true)
super.init(coder: aDecoder)
self.swifter.authorizeAppOnlyWithSuccess({ (accessToken, response) -> Void in
self.twitterIsAuthenticated = true
}, failure: { (error) -> Void in
println("Error Authenticating: \(error.localizedDescription)")
})
}
@IBAction func getUserButtonPressed(sender: UIButton?) {
if (self.twitterIsAuthenticated) {
self.getTwitterUserWithName("erhsannounce")
} else {
// Authenticate twitter again.
}
}
func getTwitterUserWithName(userName: String) {
self.swifter.getUsersShowWithScreenName(userName, includeEntities: true, success: { (user) -> Void in
if let userDict = user {
if let userId = userDict["id_str"] {
self.getTwitterStatusWithUserId(userId.string!)
}
}
}, failure: failureHandler)
}
func getTwitterStatusWithUserId(idString: String) {
let failureHandler: ((error: NSError) -> Void) = {
error in
println("Error: \(error.localizedDescription)")
}
self.swifter.getStatusesUserTimelineWithUserID(idString, count: 20, sinceID: nil, maxID: nil, trimUser: true, contributorDetails: false, includeEntities: true, success: {
(statuses: [JSONValue]?) in
if statuses != nil {
self.tweets = statuses
}
}, failure: failureHandler)
}
您似乎没有在服务器上进行身份验证。
从您的代码中我可以看到您正在使用 OAuth 身份验证初始化,但未能调用身份验证功能。
swifter.authorizeWithCallbackURL(callbackURL, success: {
(accessToken: SwifterCredential.OAuthAccessToken?, response: NSURLResponse) in
// Handle success
},
failure: {
(error: NSError) in
// Handle Failure
})
添加这个,然后调用你的 getTwitterTimeline()。
希望对您有所帮助
我将展示如何(在 2021 年)不需要每次都登录。请按照以下步骤操作(将 YOURAPPNAME 替换为您的应用名称):
在 Twitter 开发者门户的身份验证设置下添加 YOURAPPNAME:// 作为回调 URL。为此,您需要启用 3-legged OAuth,并将其添加到回调 URLS 中。您还需要输入一个网站 URL,但它可以是任何内容(我有 https://www.google.com)。还要确保(如果你想发推文)你在设置中将应用权限更改为读写。
在您的播客文件中,确保您有以下行:
pod 'Swifter' , :git => 'https://github.com/mattdonnelly/Swifter.git'
不要只使用 pod 'Swifter',因为还有另一个名为 Swifter 的项目不是由 mattdonnelly 开发的,将无法运行。
- 在 Project Explorer 中单击您的项目,select 信息选项卡。在底部,您将看到 URL 类型。展开它并单击加号。在 URL 方案中输入 YOURAPPNAME(如果您的应用程序名称是“demoApp”,请输入 demoApp 而不是 demoApp://
- 如果您的应用委托尚未使用开放 url 功能(标准是没有,但我的是因为我已经 google 登录,在我的情况下我不需要做任何事情)在你的应用委托 导入 Swifter 并添加此功能:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
Swifter.handleOpenURL(url, callbackURL: URL(string: "YOURAPPNAME://")!)
return true
}
- 在您的视图控制器中,您需要先授权 twitter,然后您可以执行任何操作(推文、查找提要等)。您可以使用 swifter.authorize 来打开浏览器。对于那些希望在第一次之后不需要它的人来说,这就是 swifter.verifyAccountCredentials 的用武之地。要找到 CONSUMER_KEY 和 CONSUMER_SECRET,请转到 Twitter 开发人员门户的密钥和令牌区域。
import Swifter
import AuthenticationServices
class ViewController: UIViewController, ASWebAuthenticationPresentationContextProviding {
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return self.view.window!
}
var swifter: Swifter!
override func viewDidLoad() {
super.viewDidLoad()
if UserDefaults.standard.string(forKey: "twitterOAuthToken") == nil {
swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET)
if let url = URL(string: "YOURAPPNAME://") {
swifter.authorize(withProvider: self, callbackURL: url) { (token, response) in
UserDefaults.standard.set(token?.key, forKey: "twitterOAuthToken")
UserDefaults.standard.set(token?.secret, forKey: "twitterOAuthSecret")
print("signed in!!")
}
}
} else {
swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET, oauthToken: UserDefaults.standard.string(forKey: "twitterOAuthToken") ?? "", oauthTokenSecret: UserDefaults.standard.string(forKey: "twitterOAuthSecret") ?? "")
swifter.verifyAccountCredentials(includeEntities: nil, skipStatus: nil, includeEmail: nil) { (json) in
print("signed in!")
} failure: { (error) in
self.swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET)
if let url = URL(string: "YOURAPPNAME://") {
self.swifter.authorize(withProvider: self, callbackURL: url) { (token, response) in
UserDefaults.standard.set(token?.key, forKey: "twitterOAuthToken")
UserDefaults.standard.set(token?.secret, forKey: "twitterOAuthSecret")
print("signed in!!")
}
}
}
}
let button = UIButton()
button.layer.backgroundColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
button.frame = CGRect(x: 200, y:0, width: 200, height: 200)
button.center = view.center
button.addTarget(self, action: #selector(tweet), for: .touchUpInside)
view.addSubview(button)
}
@objc func tweet() {
swifter.postTweet(status: "wild") { (json) in
print("tweeted!")
} failure: { (error) in
print("tweet failed")
}
}
}
我正在使用 Swifter 库在我的 Swift iOS 8 应用程序中访问 Twitter:https://github.com/mattdonnelly/Swifter。问题是我从 Twitter 收到 401 未授权错误。我仔细检查了任何可能的原因:
- 消费者key/secret错了
- 确保不要使用 API v1(使用 1.1)
这两个问题都已解决(根据 Twitter 文档),我仍然面临这个问题。我认为这与我的身份验证方式有关。我正在尝试在不使用设备上的 ACAccount 的情况下访问 public 提要。
这是我的代码:
// MARK: Twitter
var swifter: Swifter
required init(coder aDecoder: NSCoder) {
self.swifter = Swifter(consumerKey: "KEY", consumerSecret: "SECRET")
super.init(coder: aDecoder)
}
func getTwitterTimeline() {
let failureHandler: ((NSError) -> Void) = {
error in
self.alertWithTitle("Error", message: error.localizedDescription)
}
self.swifter.getStatusesUserTimelineWithUserID("erhsannounce", count: 20, sinceID: nil, maxID: nil, trimUser: true, contributorDetails: false, includeEntities: true, success: {
(statuses: [JSONValue]?) in
if statuses != nil {
self.tweets = statuses!
}
}, failure: failureHandler)
}
func alertWithTitle(title: String, message: String) {
var alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
更新: 我一直在开发该应用程序,试图实现仅使用应用程序(而非基于用户)的身份验证和访问令牌来读取 public 时间线.
我更新了代码以使用访问令牌和仅应用程序身份验证。不过还是不行。
required init(coder aDecoder: NSCoder) {
let accessToken = SwifterCredential.OAuthAccessToken(key: "KEY", secret: "SECRET")
let credential = SwifterCredential(accessToken: accessToken)
self.swifter = Swifter(consumerKey: "cKEY", consumerSecret: "cSECRET", appOnly: true)
swifter.client.credential = credential
super.init(coder: aDecoder)
}
2015 年 2 月 3 日更新
您需要使用“仅限应用程序身份验证”而不是传入 OAuth 令牌来对服务器进行身份验证。
除此之外,您在传递用户的屏幕名称时也没有正确请求带有 userId 的状态。需要用用户名获取用户id,然后请求status'。
完整的工作代码如下:
required init(coder aDecoder: NSCoder) {
self.swifter = Swifter(consumerKey: "cKEY", consumerSecret: "cSECRET", appOnly: true)
super.init(coder: aDecoder)
self.swifter.authorizeAppOnlyWithSuccess({ (accessToken, response) -> Void in
self.twitterIsAuthenticated = true
}, failure: { (error) -> Void in
println("Error Authenticating: \(error.localizedDescription)")
})
}
@IBAction func getUserButtonPressed(sender: UIButton?) {
if (self.twitterIsAuthenticated) {
self.getTwitterUserWithName("erhsannounce")
} else {
// Authenticate twitter again.
}
}
func getTwitterUserWithName(userName: String) {
self.swifter.getUsersShowWithScreenName(userName, includeEntities: true, success: { (user) -> Void in
if let userDict = user {
if let userId = userDict["id_str"] {
self.getTwitterStatusWithUserId(userId.string!)
}
}
}, failure: failureHandler)
}
func getTwitterStatusWithUserId(idString: String) {
let failureHandler: ((error: NSError) -> Void) = {
error in
println("Error: \(error.localizedDescription)")
}
self.swifter.getStatusesUserTimelineWithUserID(idString, count: 20, sinceID: nil, maxID: nil, trimUser: true, contributorDetails: false, includeEntities: true, success: {
(statuses: [JSONValue]?) in
if statuses != nil {
self.tweets = statuses
}
}, failure: failureHandler)
}
您似乎没有在服务器上进行身份验证。
从您的代码中我可以看到您正在使用 OAuth 身份验证初始化,但未能调用身份验证功能。
swifter.authorizeWithCallbackURL(callbackURL, success: {
(accessToken: SwifterCredential.OAuthAccessToken?, response: NSURLResponse) in
// Handle success
},
failure: {
(error: NSError) in
// Handle Failure
})
添加这个,然后调用你的 getTwitterTimeline()。
希望对您有所帮助
我将展示如何(在 2021 年)不需要每次都登录。请按照以下步骤操作(将 YOURAPPNAME 替换为您的应用名称):
在 Twitter 开发者门户的身份验证设置下添加 YOURAPPNAME:// 作为回调 URL。为此,您需要启用 3-legged OAuth,并将其添加到回调 URLS 中。您还需要输入一个网站 URL,但它可以是任何内容(我有 https://www.google.com)。还要确保(如果你想发推文)你在设置中将应用权限更改为读写。
在您的播客文件中,确保您有以下行:
pod 'Swifter' , :git => 'https://github.com/mattdonnelly/Swifter.git'
不要只使用 pod 'Swifter',因为还有另一个名为 Swifter 的项目不是由 mattdonnelly 开发的,将无法运行。
- 在 Project Explorer 中单击您的项目,select 信息选项卡。在底部,您将看到 URL 类型。展开它并单击加号。在 URL 方案中输入 YOURAPPNAME(如果您的应用程序名称是“demoApp”,请输入 demoApp 而不是 demoApp://
- 如果您的应用委托尚未使用开放 url 功能(标准是没有,但我的是因为我已经 google 登录,在我的情况下我不需要做任何事情)在你的应用委托 导入 Swifter 并添加此功能:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
Swifter.handleOpenURL(url, callbackURL: URL(string: "YOURAPPNAME://")!)
return true
}
- 在您的视图控制器中,您需要先授权 twitter,然后您可以执行任何操作(推文、查找提要等)。您可以使用 swifter.authorize 来打开浏览器。对于那些希望在第一次之后不需要它的人来说,这就是 swifter.verifyAccountCredentials 的用武之地。要找到 CONSUMER_KEY 和 CONSUMER_SECRET,请转到 Twitter 开发人员门户的密钥和令牌区域。
import Swifter
import AuthenticationServices
class ViewController: UIViewController, ASWebAuthenticationPresentationContextProviding {
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return self.view.window!
}
var swifter: Swifter!
override func viewDidLoad() {
super.viewDidLoad()
if UserDefaults.standard.string(forKey: "twitterOAuthToken") == nil {
swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET)
if let url = URL(string: "YOURAPPNAME://") {
swifter.authorize(withProvider: self, callbackURL: url) { (token, response) in
UserDefaults.standard.set(token?.key, forKey: "twitterOAuthToken")
UserDefaults.standard.set(token?.secret, forKey: "twitterOAuthSecret")
print("signed in!!")
}
}
} else {
swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET, oauthToken: UserDefaults.standard.string(forKey: "twitterOAuthToken") ?? "", oauthTokenSecret: UserDefaults.standard.string(forKey: "twitterOAuthSecret") ?? "")
swifter.verifyAccountCredentials(includeEntities: nil, skipStatus: nil, includeEmail: nil) { (json) in
print("signed in!")
} failure: { (error) in
self.swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET)
if let url = URL(string: "YOURAPPNAME://") {
self.swifter.authorize(withProvider: self, callbackURL: url) { (token, response) in
UserDefaults.standard.set(token?.key, forKey: "twitterOAuthToken")
UserDefaults.standard.set(token?.secret, forKey: "twitterOAuthSecret")
print("signed in!!")
}
}
}
}
let button = UIButton()
button.layer.backgroundColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
button.frame = CGRect(x: 200, y:0, width: 200, height: 200)
button.center = view.center
button.addTarget(self, action: #selector(tweet), for: .touchUpInside)
view.addSubview(button)
}
@objc func tweet() {
swifter.postTweet(status: "wild") { (json) in
print("tweeted!")
} failure: { (error) in
print("tweet failed")
}
}
}