Twitter に任意の位置情報 (緯度・経度) を付加してツイート投稿する iOS アプリのサンプルコードを書いてみた。 Storyboard を使わずに、GUIを組み立てなくても、サンプルコードをコピペして動作する。

今回の動作確認環境: Xcode 7.2 + Swift 2.1.1 + 実機 iPhone 6 + iOS 9.2

Xcode で新規に Single View Application のプロジェクトを作成して、

Swift で位置情報付きの Twitter 投稿するサンプルコード (Storyboard を使わないお手軽コピペ版)

Xcode のメニューから [File] → [New] → [File...] → [iOS] → [Source] → [Swift File] にて、「TwitterManager.swift」というファイル名で Swift のファイルを追加する。

以下のコードを追加した TwitterManager.swift に上書きコピペする。このコードに Twitter 関連の処理をできるだけまとめておいた。


//
//  TwitterManager.swift
//

import UIKit
import Accounts
import Social

class TwitterManager: NSObject {
    
    // iOS 端末で使用可能な Twitter アカウントの一覧を取得する
    func getTwitterAccounts(completion:(accounts:[ACAccount]?, error: NSError?) -> Void) {

        let accountStore = ACAccountStore()
        let accountType = accountStore.accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter)
        
        accountStore.requestAccessToAccountsWithType(accountType, options: nil) { (granted:Bool, error:NSError?) -> Void in
            
            if let err = error {
                completion(accounts: nil, error: err)
                return;
            }
            
            if !granted {
                let info = [NSLocalizedDescriptionKey: "Cannot access to account data"]
                let nserr = NSError.init(domain: "", code: -1, userInfo: info)
                completion(accounts: nil, error: nserr)
                return;
            }
            
            let accounts = (accountStore.accountsWithAccountType(accountType) as? [ACAccount])!
            completion(accounts: accounts, error: nil)
        }
    }
    
    // アカウント選択のActionSheetを表示する
    func showAccountSelectSheet(view: UIViewController, accounts: [ACAccount], completion:(account: ACAccount?) -> Void) {
        
        let alert = UIAlertController(title: "Twitter",
            message: "アカウントを選択してください",
            preferredStyle: .ActionSheet)
        
        // アカウント選択のActionSheetを表示するボタン
        for account in accounts {
            alert.addAction(UIAlertAction(title: account.username,
                style: .Default,
                handler: { (action) -> Void in
                    completion(account: account)
            }))
        }
        
        // キャンセルボタン
        alert.addAction(UIAlertAction(title: "キャンセル", style: .Cancel, handler: nil))
        
        // 表示する
        dispatch_async(dispatch_get_main_queue(), {
            view.presentViewController(alert, animated: true, completion: nil)
        })
    }
    
    // ツイートを投稿
    func postTweet(account: ACAccount, status: String, lat: String, long: String, completion:(error: NSError?) -> Void) {

        let URL = NSURL(string: "https://api.twitter.com/1.1/statuses/update.json")
        
        // ツイートしたい文章をセット
        let params = ["status": status, "lat": lat, "long": long]
        
        // リクエストを生成
        let request = SLRequest(forServiceType: SLServiceTypeTwitter,
            requestMethod: .POST,
            URL: URL,
            parameters: params as [NSObject : AnyObject])

        // 取得したアカウントをセット
        request.account = account
        
        // APIコールを実行
        request.performRequestWithHandler { (responseData, urlResponse, error) -> Void in
            
            if error != nil {
                completion(error: error)
            }
            else {
                // 結果の表示
                do {
                    let result = try NSJSONSerialization.JSONObjectWithData(responseData, options: .AllowFragments) as! NSDictionary
                    print("\(result)") // JSON デバッグ出力
                    let errors = result["errors"] as! NSArray?
                    if let errs = errors {
                        // エラーあり (Status is a duplicate など Twitter API が返すエラー)
                        let message = errs[0]["message"] as! NSString
                        let info = [NSLocalizedDescriptionKey: "Twitter API Response Error: " + (message as String)]
                        let nserr = NSError.init(domain: "", code: -1, userInfo: info)
                        completion(error: nserr)
                    }else{
                        // エラーなし
                        completion(error: nil)
                    }
                } catch let error as NSError {
                    // エラー
                    completion(error: error)
                }
            }
        }
    }
}

以下のコードを ViewController.swift に上書きコピペする。


//
//  ViewController.swift
//

import UIKit
import Accounts
import Social

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        buildToolbar()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    // ツールバーを作る
    private func buildToolbar() {
        
        // ツールバー
        let toolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.bounds.size.width, 44.0))
        toolbar.layer.position = CGPoint(x: self.view.bounds.width / 2, y: self.view.bounds.height - 22.0)
        
        // ボタン
        let tweetButton = UIBarButtonItem(title: "ツイートする", style: .Plain, target: self, action: "onClickTweetButton:")
        toolbar.items = [tweetButton]
        
        // ツールバーを画面に追加
        self.view.addSubview(toolbar)
    }
    
    // ボタンを押したときの処理
    func onClickTweetButton(sender: UIBarButtonItem) {
        
        let tm = TwitterManager()
        tm.getTwitterAccounts({(accounts:[ACAccount]?, error: NSError?) -> Void in
            if(accounts == nil){
                if let err = error{
                    self.showAlertDialog(self, title: "ERROR", message: err.userInfo.description)
                }
            }
            tm.showAccountSelectSheet(self, accounts: accounts!, completion: {(account: ACAccount?) -> Void in
                tm.postTweet(account!, status: "TEST: 大名古屋ビルヂング", lat: "35.172076", long: "136.884607", completion:{(error: NSError?) -> Void in
                    if let err = error {
                        self.showAlertDialog(self, title: "ERROR", message: err.userInfo.description)
                    }
                })
            })
        })
    }
    
    // アラートダイアログを表示する
    private func showAlertDialog(view: UIViewController, title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
        dispatch_async(dispatch_get_main_queue(), {
            view.presentViewController(alert, animated: true, completion: nil)
        })
    }
    
}

プログラムを実行すると、真っ白な画面の左下に「ツイートする」とテキストが表示される。

Swift で位置情報付きの Twitter 投稿するサンプルコード (Storyboard を使わないお手軽コピペ版)

「ツイートする」をタップすると、iOS に設定されている Twitter アカウントを一覧表示して、アカウントを選択するダイアログが表示される。選択すると、テストデータ「大名古屋ビルヂング」と位置情報 (lat: "35.172076", long: "136.884607") がツイートされる。

Swift で位置情報付きの Twitter 投稿するサンプルコード (Storyboard を使わないお手軽コピペ版)

任意の位置情報を付加しなくて良いなら Swift で Twitter 投稿するサンプルコード (Storyboard を使わないお手軽コピペ版) のほうがお手軽でラク。

tags: swift twitter

Posted by NI-Lab. (@nilab)