Twitter に任意の位置情報 (緯度・経度) を付加してツイート投稿する iOS アプリのサンプルコードを書いてみた。 Storyboard を使わずに、GUIを組み立てなくても、サンプルコードをコピペして動作する。
今回の動作確認環境: Xcode 7.2 + Swift 2.1.1 + 実機 iPhone 6 + iOS 9.2
Xcode で新規に Single View Application のプロジェクトを作成して、
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)
})
}
}
プログラムを実行すると、真っ白な画面の左下に「ツイートする」とテキストが表示される。
「ツイートする」をタップすると、iOS に設定されている Twitter アカウントを一覧表示して、アカウントを選択するダイアログが表示される。選択すると、テストデータ「大名古屋ビルヂング」と位置情報 (lat: "35.172076", long: "136.884607") がツイートされる。
任意の位置情報を付加しなくて良いなら Swift で Twitter 投稿するサンプルコード (Storyboard を使わないお手軽コピペ版) のほうがお手軽でラク。
-
ref.
- [ヅ] Swift で Twitter 投稿するサンプルコード (Storyboard を使わないお手軽コピペ版) (2015-11-17)
- ACAccount Class Reference
- ACAccountStore Class Reference
- SLRequest Class Reference
- POST statuses/update | Twitter Developers
- iOSアプリでTwitterのタイムライン取得・ツイート投稿を行う(Accounts.frameworkとSocial.rameworkを使って) - Think Big Act Local
- Swift - クラスを使ってツイッターAPIのモジュールを作ろう - Qiita
tags: swift twitter
Posted by NI-Lab. (@nilab)