Classの解説とメリット
ここからは、Classを使ってTwitterサービスモジュールを作っていきます。
今までもViewControllerやUIパーツなどで、自然と使ってきましたが今回はこのクラスを使ってTwitterAPIを使うためのモジュールを作成していきます。
Swiftのクラスの特徴として、C++やObjective-Cのようにヘッダーファイルを分ける必要がありません。全て1つのファイルに書くことができます。また、クラスはプロパティを持つことができます。クラスにプロパティを持たせることによって、必要な時にデータをわざわざ維持したり取得したりすることを減らせます。
なぜモジュール化するかというと、今までは各画面で同じFrameworkを読み込んだりユーザーデータを受け渡したりする必要があり、新しいビュークラスを実装するたびに同じものを使うために同じような実装をすることが多々ありました。
モジュール化することで各ビューで同じ実装をしなくても、モジュールを読み込むことでほとんど実装なく同様にAPIを利用することができるようになり、コード量もオーバーヘッドも減らすことができます。
Classを使った開発アプローチと実装
では、モジュールを実装していきます。
import UIKit
import Accounts
import Social
class TwitterServiceManager: NSObject {
var accountStore = ACAccountStore()
var twAccount = ACAccount?()
var accounts:[ACAccount]?
var tweets = []
func initWithId(id:Int) {
setId(id);
}
func setId(id:Int)
{
NSUserDefaults.standardUserDefaults().setInteger(id, forKey: "TwitterUserListIndex")
}
func myId() -> Int
{
return NSUserDefaults.standardUserDefaults().objectForKey("TwitterUserListIndex")!.integerValue
}
func myAccount() -> ACAccount
{
return accountList()[myId()]
}
func accountList() -> [ACAccount]
{
return accounts!
}
// Twitter APIを使ってタイムラインを取得しtweetsに保存する
func fetchTimeline(completion:(success:Bool) -> Void)
{
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
let URL = NSURL(string: "https://api.twitter.com/1.1/statuses/home_timeline.json")
let request = SLRequest(forServiceType: SLServiceTypeTwitter, requestMethod: .GET, URL: URL, parameters: nil)
request.account = twAccount
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
request.performRequestWithHandler { (data, response, error:NSError?) -> Void in
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
if error != nil {
println("Fetching Error: \(error)")
completion(success: false)
return
}
var tweetResponse: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: nil)
if let tweetDict = tweetResponse as? Dictionary<String, AnyObject>{
completion(success: false)
return
}
self.tweets = tweetResponse as! NSArray
completion(success: true)
}
}
func fetchAccountsList(completion:(success:Bool) -> Void)
{
let accountType = accountStore.accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter)
accountStore.requestAccessToAccountsWithType(accountType, options: nil) { (granted:Bool, aError:NSError?) -> Void in
if let error = aError {
println("Error! - \(error)")
completion(success: false)
return;
}
if !granted {
println("Cannot access to account data")
completion(success: false)
return;
}
self.accounts = (self.accountStore.accountsWithAccountType(accountType) as? [ACAccount])!
completion(success: true)
}
}
func sendTweet(tweet:String, completion:(success:Bool) -> Void)
{
let URL = NSURL(string: "https://api.twitter.com/1.1/statuses/update.json")
if count(tweet) <= 0 {
// var alert = UIAlertController(title: "Error", message: "Please input text", preferredStyle: UIAlertControllerStyle.Alert)
// alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:nil))
// self.presentViewController(alert, animated: true, completion:nil)
completion(success: false)
return
}
var params = ["status": tweet]
// リクエストを生成
let request = SLRequest(forServiceType: SLServiceTypeTwitter,
requestMethod: .POST,
URL: URL,
parameters: params)
// 取得したアカウントをセット
request.account = twAccount
// APIコールを実行
request.performRequestWithHandler { (responseData, urlResponse, error) -> Void in
if error != nil {
println("error is \(error)")
completion(success: false)
}
else {
// 結果の表示
let result = NSJSONSerialization.JSONObjectWithData(responseData, options: .AllowFragments, error: nil) as! NSDictionary
completion(success: true)
println("result is \(result)")
}
}
}
}
まとめ
- クラスはUIパーツやViewControllerなどの部品をつくるベースになっている
- クラスを使ってデータをネット通信やデータなどを集約したモジュールを作れる
- データやネットワークのモジュールを作ることでUIやViewControllerの実装をシンプルにできる