LoginSignup
12
16

More than 3 years have passed since last update.

Swifterを自分のアプリに組み込む方法

Last updated at Posted at 2019-08-18

@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です。

スクリーンショット 2019-08-19 0.27.55.png

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のアプリで画面構成は下記のようになります。

スクリーンショット 2019-08-19 0.54.55.png

説明よりも実際のコードを紹介します。

ViewController.swift
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が設定されていないことが原因。
下記のように設定を行う。

スクリーンショット 2019-08-19 11.57.33.png

12
16
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
16