Help us understand the problem. What is going on with this article?

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

@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

noby111
ARKitを使って個人アプリ開発をしています。 最近はFIDOを勉強しています。
https://portfolio-e3de3.firebaseapp.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした