@k-boyさんの記事を参考にSwifterを自分のアプリに組み込んでみたのですが、色々とつまづいたので備忘のため手順を残しておきます。
使用したバージョン
- Xcode : 10.3
- Swifter : 1.7.0
1. 自分のアプリにCocoaPodでSwifterをインストールする
- 自分のアプリディレクトリに移動し、
$ pod init
を実行する - Podfileが作成されるので
pod 'Swifter', :git => 'https://github.com/mattdonnelly/Swifter.git'
を追記する -
$ pod install
を実行する
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'MyTweetTool' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for MyTweetTool
pod 'Swifter', :git => 'https://github.com/mattdonnelly/Swifter.git'
pod 'SwiftGifOrigin', '~> 1.7.0'
end
2. Twitter Developersで自分のアプリを登録する
Twitter Developersに自分のアプリを登録します。
細かい手順は割愛しますが@tdknさんの記事が参考になります。
登録が完了し、最終的に下記のように自分のConsumer API keysが確認できればOKです。
3. Custom URL Schemeを設定する
SwifterはOAuthにてAPIの認証を行うため、一時的にブラウザを開きます。
開いた先から自分のアプリに戻って来られるようにCustome URL Schemeを設定します。
- Info.plistに自分のCFBundleURLTypes定義を追加する
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>swifter-{Consumer API key}</string>
</array>
</dict>
</array>
※CFBundleURLSchemesにswifter-{Consumer API key}とありますが、{Consumer API key}には先程のTwitter DevelopersのAPI keyを入力します
- AppDelegate.swiftでapplication:openURL:options:をオーバーライドする
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return Swifter.handleOpenURL(url, callbackURL: URL(string: "swifter-{Consumer API key}://")!)
}
※Swifterのコードを呼び出すのでimport SwifteriOS
が必要です
4. Swifterを使ってtweetを投稿する
自分が作成したのはテキスト入力と投稿ボタンだけのシンプルなUIのアプリで画面構成は下記のようになります。
説明よりも実際のコードを紹介します。
import UIKit
import SwifteriOS
import SafariServices
class ViewController: UIViewController, SFSafariViewControllerDelegate {
@IBOutlet weak var tweetMsgArea: UITextView!
private let appStatus = AppStatus()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func tweetPushed(_ sender: Any) {
tweet()
}
func tweet() {
let TWITTER_CONSUMER_KEY = "{Consumer API key}"
let TWITTER_CONSUMER_SECRET = "{Consumer API secret key}"
// load from UserDefaults
let tokenKey = self.appStatus.twitterTokenKey
let tokenSecret = self.appStatus.twitterTokenSecret
if tokenKey == nil || tokenSecret == nil {
let swifter = Swifter(consumerKey: TWITTER_CONSUMER_KEY, consumerSecret: TWITTER_CONSUMER_SECRET)
swifter.authorize(
withCallback: URL(string: "swifter-{Consumer API key}://")!,
presentingFrom: self,
success: { accessToken, response in
print(response)
guard let accessToken = accessToken else { return }
self.appStatus.twitterTokenKey = accessToken.key
self.appStatus.twitterTokenSecret = accessToken.secret
self.tweet()
}, failure: { error in
print(error)
})
} else {
let swifter = Swifter(consumerKey: TWITTER_CONSUMER_KEY, consumerSecret: TWITTER_CONSUMER_SECRET, oauthToken: tokenKey!, oauthTokenSecret: tokenSecret!)
swifter.postTweet(status: tweetMsgArea.text, success: { response in
print(response)
}, failure: { error in
print(error)
})
}
}
}
class AppStatus {
var userdefault = UserDefaults.init(suiteName: "app_status")!
var twitterTokenKey : String? {
get {
if let token : String = userdefault["token_key"] {
return token
} else {
return nil
}
}
set {
userdefault["token_key"] = newValue
}
}
var twitterTokenSecret : String? {
get {
if let secret : String = userdefault["token_secret"] {
return secret
} else {
return nil
}
}
set {
userdefault["token_secret"] = newValue
}
}
}
extension UserDefaults {
subscript<T: Any>(key: String) -> T? {
get {
if let value = object(forKey: key) {
return value as? T
} else {
return nil
}
}
set(_newValue) {
if let newValue = _newValue {
set(newValue, forKey: key)
} else {
removeObject(forKey: key)
}
synchronize()
}
}
}
ポイントとしてはUserDefaultsからアクセストークンを取得し、取得できなかった場合はSwifter.authorize()
を呼び出してアクセストークンを取得します。
既に取得できていた場合はそのままSwifter.postTweet()
で入力された内容をTweetします。
5. トラブルシュート
dyld: Library not loaded: ... Reason: image not foundと出る場合
Embedded BinariesにSwifteriOSが設定されていないことが原因。
下記のように設定を行う。