概要
- SwiftとParseを使用して、ユーザー登録と140文字以内のテキストのポストをする
- Twitterのように、他の人のポスト内容がタイムラインとして表示される
- Parseを使うので、ローカルDBは不要で、超簡単にデータベースを作成でき、カラム追加やデータ作成ができる
Github
Other Contents about Swift
- SwiftのNotificationでHello, Worldして、アクションを3つ作ってみた(Xcode6 beta4)
- SwiftでTo Doリストを作ってみた(Xcode6 beta4, Tabbed Application, UITableView, UITextField)
手順
1. Parse.com側の設定
- 30req/sまでは無料で使える!
- まず、ユーザー登録などをしておく
- 続いて、Parse.comでCreate New Appをする
- 色々出てくるが、無視して”QuickStartGuide"を押す
- data -> mobile -> iOS -> ObjectiveC -> Existing Projectと進む
- 進んでいった先のページに書いてある通りに準備を行う
- SDKのインストール
- Parse.comを利用するために必要なFrameworksを入れる
- 必要なFrameworkは合計10個なので、抜け漏れがないように注意。
2. XcodeでParseと接続テスト
- Xcodeの方で、New File(cmd+N)して、Obj-Cでファイルを作成。ファイル名は何でもOK。ここではhogeとした。
- hoge.mとProjectName-Bridging-Header.hという2つのファイルが生成される。
- hoge.mというファイルは不要なので、削除する。また、ProjectName-Bridging-Header.hに下記コードを追加する。
ProjetName-Bridging-Header.swift
#import <Parse/Parse.h>
- 続いて、Parse.comにObj-Cで書いてある初期設定をSwiftに書き換えてみて、下記のようなテストオブジェクトを生成する。(下記はSwiftに書き換え済み)
AppDelegate.swift
// Parse.comの設定
Parse.setApplicationId("ClientID", clientKey: "ClientKEY")
var testObject:PFObject = PFObject(className: "TestObject")
testObject["foo"] = "bar"
testObject.setObject("user1", forKey: "user")
// 上記コードの説明は以下。
// var 適当な変数:PFObject = PFObject(className: "テーブル名")
// testObject["カラム名"] = "テスト用に突っ込むデータ"
// testObject.setObject("テスト用に突っ込むデータ", forKey: "カラム名")
testObject.saveInBackground()
/* こちらがParseのIntroductionに書いてあるObj-cの元のコード。一応張っておきます。
[Parse setApplicationId:@"ClientID"
clientKey:@"ClientKEY"];
PFObject *testObject = [PFObject objectWithClassName:@"TestObject"];
testObject[@"foo"] = @"bar";
[testObject saveInBackground];
*/
- これだけでParseとの接続が完了☆
- このあとParse.comにあるtestボタンを押してみて”Congrats!"が表示されれば接続完了!
- テストが完了したら、上記のコードは削除してOK
3. Tweet機能の実装
3-1. StoryboardにTableViewControllerを追加。NavigationControllerも追加して、それをTableViewControllerに追加する
- Label2個(ユーザー名とポスト時間を表示するためのもの)とTextView(140文字のテキストを入力するためのフォーム)を追加して、Bar Button(新しく投稿するためのもの)をTableViewControllerに追加。
- ViewController(新しいポストをする画面のためのもの)を生成して、TableViewControllerのBar buttonとpushの関係でひもづける
3-2. StoryboardとControllerをひもづける
- cmd+NでNew Fileして、Cocoa Touch Classを選択
- TimelineTableViewControllerとComposeViewControllerを作成
- それぞれのControllerをStoryBoardにひもづける。
- さらにCocoa Touch ClassでTweetTableViewCellを作成し、Timeline Table ViewのCellにひもづける。(ひもづける時は、左下のレイヤーを表示するボタンを押してやる)
- 右カラムのインスペクターからTable View Cellのidentifierを”Cell”に変更
3-3. ユーザー作成のためのAlertポップアップを作成する
TimelineTableViewController.swift
// アプリを起動した時にログインアラートを表示する。viewDidLoadではないので注意。
override func viewDidAppear(animated: Bool) {
if (!PFUser.currentUser()) {
var loginAlert:UIAlertController = UIAlertController(title: "Sign UP / Loign", message: "Plase sign up or login", preferredStyle: UIAlertControllerStyle.Alert)
// ユーザーネームとパスワードの入力
loginAlert.addTextFieldWithConfigurationHandler({
textfield in
textfield.placeholder = "Your username"
})
loginAlert.addTextFieldWithConfigurationHandler({
textfield in
textfield.placeholder = "Your Password"
textfield.secureTextEntry = true
})
loginAlert.addAction(UIAlertAction(title: "Login", style: UIAlertActionStyle.Default, handler: {
alertAction in
let textFields:NSArray = loginAlert.textFields as NSArray
let usernameTextfield:UITextField = textFields.objectAtIndex(0) as UITextField
let passwordTextfield:UITextField = textFields.objectAtIndex(1) as UITextField
// ここではtweeterをユーザーの変数として作成
var tweeter:PFUser = PFUser()
// UITextFieldに入力された内容を代入する
tweeter.username = usernameTextfield.text
tweeter.password = passwordTextfield.text
// Parseに送信
tweeter.signUpInBackgroundWithBlock{
(success:Bool!, error:NSError!)->Void in
if !error{
println("Sign up successful")
}else{
let errorString = error.userInfo["error"] as NSString
println(errorString)
}
}
}))
self.presentViewController(loginAlert, animated: true, completion: nil)
}
}
- ここでiOS Simulatorを立ち上げてみて、ログインをしてみる
- そのあと、Parse.comに行ってDashboardをリロードすると今作成したユーザーが出てくる(お手軽!)
3-4. Tweetsテーブルの作成
ComposeViewController.swift
@IBAction func sendTweet(sender: AnyObject) {
// Tweetする内容を保存するclass(テーブル)の作成
var tweet:PFObject = PFObject(className: "Tweets")
// カラムを作成する。ここでは、ユーザーとTweet内容用のカラムを作成。
tweet["content"] = tweetTextView.text
tweet["tweeter"] = PFUser.currentUser()
// Parseに送信
tweet.saveInBackground()
// Tweet一覧が表示されるTimelineTableViewControllerに戻る
self.navigationController.popToRootViewControllerAnimated(true)
}
- ComposeViewControllerがParse.comとのTweetの連携をしたので、Tweetしてみて、Parse.comのDashboardをリロードすると新たなテーブルが出てきて、反映されていることが確認できる
4. 投稿したTweet内容を取得して、Viewに表示する
TimelineTableViewController.swift
var timelineData:NSMutableArray = NSMutableArray()
// beta5からinitの前方にrequiredが必要になった
required init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
// Parseからデータの取得
func loadData(){
timelineData.removeAllObjects()
// Tweetsテーブルを呼び出す
var findTimelineData:PFQuery = PFQuery(className: "Tweets")
findTimelineData.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if !error{
for object in objects{
self.timelineData.addObject(object)
}
let array:NSArray = self.timelineData.reverseObjectEnumerator().allObjects
self.timelineData = array as NSMutableArray
self.tableView.reloadData()
}
}
}
- ログイン、サインアップのアラートのコードの上部に下記を追加(viewDidAppearの所)
TimelineTableViewController.swift
// tweetのデータを取得
self.loadData()
- UITableViewに関連するコードも追加する
TimelineTableViewController.swift
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
// Tweetsデータの数だけrowを返す
return timelineData.count
}
- Tweetの内容とユーザーをParseから取得する
TimelineTableViewController.swift
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell:TweetTableViewCell = tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as TweetTableViewCell
let tweet:PFObject = self.timelineData.objectAtIndex(indexPath!.row) as PFObject
// デザイン部分なので無視してOK
cell.tweetTextView.alpha = 0
cell.timestampLabel.alpha = 0
cell.usernameLabel.alpha = 0
// Tweetの内容をParse.comから取得
cell.tweetTextView.text = tweet.objectForKey("content") as String
var dataFormatter:NSDateFormatter = NSDateFormatter()
dataFormatter.dateFormat = "yyyy-MM-dd HH:mm"
cell.timestampLabel.text = dataFormatter.stringFromDate(tweet.createdAt)
// objectIdをforeignKeyとして、user(tweeter)を取得
var findTweeter:PFQuery = PFUser.query()
findTweeter.whereKey("objectId", equalTo: tweet.objectForKey("tweeter").objectId)
findTweeter.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if !error{
let user:PFUser = (objects as NSArray).lastObject as PFUser
cell.usernameLabel.text = "@\(user.username)"
// CELLの表示にDurationをつけて、ほわっと表示する
UIView.animateWithDuration(0.5, animations: {
cell.tweetTextView.alpha = 1
cell.timestampLabel.alpha = 1
cell.usernameLabel.alpha = 1
})
}
}
// Configure the cell...
return cell
}
- 入力しているときの残り文字数のカウント
ComposeViewContorller.swift
func textView(textView: UITextView!,
shouldChangeTextInRange range: NSRange,
replacementText text: String!) -> Bool{
// 入力文字数のカウント
var newLength:Int = (textView.text as NSString).length + (text as NSString).length - range.length
var remainingChar: Int = 140 - newLength
charRemainingLabel.text = "残り\(remainingChar)"
return (newLength > 140) ? false : true
}
★女性エンジニア向けのイベントやります
9/17(水)開催 - ZIGExN Swift Girls 〜集え☆iPhoneアプリを作りたい女子〜