Parseとはなんぞや
バックエンドをswift(Obj-c)だけで簡単に実装できてしまうもの。
ここではざっくり説明していきます。
詳しくはParse iOS Guidをみて下さい。
ParseのDBの接続部分だけ見たい方は目次の[ParseDB連携]で飛んで下さい。
作成するアプリ
Twitterのようなアプリを作成しながら、Parseのありがたさを見ていきます。
メインはParseで用意されているDB(データベース)に保存するところですね。
Parse.comに新規登録
まずは、Parse.comに登録します。
登録完了したら、ホーム画面の右上の『Go to your apps』をクリック。
次の画面では、Parse上にアプリ新しく作ります。その時に、アプリ名を設定します。
作成されたアプリをクリックすると...
アプリの管理ページが登場
ここのページで保存したデータなどを確認するわけですねえ。
ここまでで、一旦Parse側の操作は終わりです。
Xcode側で新規プロジェクトを作成
いつものように、Xcodeのプロジェクトを作ります。
SDKのインポート
作成したプロジェクトにParseに用意されている、SDKをインポートします。
Prase.comに戻り、アプリ管理ページの下部の[Downloads]をクリック
SDKをクリックすると、SDKをダウンロードすることができます。
ダウンロードしたzipファイルを解凍し、その中の以下の2つのファイルをXcodeにドラッグ&ドロップでインポートしましょう。
- Parse.framework
- Bolts.framework
その他の必要なフレームワークをインポート
先程の2つのフレームワーク以外に必要なものをインポートします。
以下の画像のように、Linked Frameworks and Libraries まで行き、必要なフレームワークを追加します。
追加するファイル以下のものです。
- AudioToolbox.framework
- CFNetwork.framework
- CoreGraphics.framework
- CoreLocation.framework
- MobileCoreServices.framework
- QuartzCore.framework
- Security.framework
- StoreKit.framework
- SystemConfiguration.framework
- libsqlite3.dylib
- libz.dylib
Parseで作成したアプリとXcodeのプロジェクトの紐付け
現段階では、Parse.comで作成したアプリと、Xcodeで作成したプロジェクトは独立しているので、
Parse.comで発行される、keyを用いて紐付けます。
Parse.com
- Application ID
- Client Key
この2つを使用します。
Xcodeプロジェクト
AppDelegate.swiftに以下のように編集します。
import UIKit
import Parse //Parseをインポート
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//Parseで取得した[Application ID]と[Client Key]を指定
Parse.setApplicationId("[Application ID]", clientKey: "[Client Key]")
return true
}
以上の操作で、連携は完了です。
UIの作成と必要なSwiftファイルの追加
Main.storyboard上はざっくりこんな感じです。
必要なファイルを作成します。
- Models
- Tweet.swift(NSObject)
- TweetManager.swift(NSObject)
- Views
- TweetTableViewCell.swift(UITableViewCell)
- TweetTableViewCell.xib
- ViewControllers
- TweetsTableViewController.swift(UITableViewController)
- NewTweetViewController.swfit(UIViewController)
今回は、Parseで用意さえたDBとの接続がメインなので、それ以外の部分はざざざっと書いていきます。
import UIKit
import Parse
class Tweet: NSObject {
var name: String!
var text: String!
init(name: String, text: String) {
self.name = name
self.text = text
}
func saveTweet() {
//後ほどParseのdbに保存する処理を書く
}
}
import UIKit
import Parse
class TweetManager: NSObject {
var tweets: Array<Tweet> = []
static let sharedInstance = TweetManager()
func fetchTweets(callback: () -> Void) {
//後ほどParseのdbからツイート情報を取得する処理を記述
}
}
import UIKit
class TweetTableViewCell: UITableViewCell {
@IBOutlet weak var tweetLabel: UILabel!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var tweetImageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
tweetLabel.numberOfLines = 0
tweetImageView.clipsToBounds = true
tweetImageView.contentMode = UIViewContentMode.ScaleAspectFill
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
import UIKit
class TweetsTableViewController: UITableViewController {
let tweetCollection = TweetManager.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerNib(UINib(nibName: "TweetTableViewCell", bundle: nil), forCellReuseIdentifier: "TweetTableViewCell")
tableView.estimatedRowHeight = 90
tableView.rowHeight = UITableViewAutomaticDimension
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "New", style: UIBarButtonItemStyle.Plain, target: self, action: "showNewTweetViewController")
let callback = { () -> Void in
self.tableView.reloadData()
}
tweetCollection.fetchTweets(callback)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tweetCollection.tweets.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TweetTableViewCell", forIndexPath: indexPath) as! TweetTableViewCell
let tweet = tweetCollection.tweets[indexPath.row]
cell.tweetImageView.image = UIImage(named: "omoto")
cell.nameLabel.text = tweet.name
cell.tweetLabel.text = tweet.text
return cell
}
func showNewTweetViewController() {
performSegueWithIdentifier("toNewViewController", sender: nil)
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
}
import UIKit
class NewTweetViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var placeholderLabel: UILabel!
@IBOutlet weak var tweetButton: UIButton!
@IBOutlet weak var tweetTextView: UITextView!
@IBOutlet weak var nameTextfield: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
tweetTextView.delegate = self
tweetButton.layer.cornerRadius = 5
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func textViewShouldBeginEditing(textView: UITextView) -> Bool {
placeholderLabel.hidden = true
return true
}
func textViewShouldEndEditing(textView: UITextView) -> Bool {
if textView.text.isEmpty {
placeholderLabel.hidden = false
}
return true
}
@IBAction func tapTweetButton(sender: UIButton) {
if nameTextfield.text.isEmpty || tweetTextView.text.isEmpty {
println("Name or text is empty")
} else {
let tweet = Tweet(name: nameTextfield.text, text: tweetTextView.text)
tweet.saveTweet()
navigationController?.popViewControllerAnimated(true)
}
}
}
一旦ここまで。
ParseのDB連携
いよいよ今回のメインです。
DBにデータを保存
Tweet.swiftのsaveTweet()を編集していきます。
import UIKit
import Parse
class Tweet: NSObject {
var name: String!
var text: String!
init(name: String, text: String) {
self.name = name
self.text = text
}
func saveTweet() {
let tweetsObject = PFObject(className: "tweets")
tweetsObject["name"] = name
tweetsObject["text"] = text
tweetsObject.saveInBackgroundWithBlock { (success, error) -> Void in
if success {
println("Tweet has been saved")
}
}
}
}
それぞれ解説していきます。
PFObject(className: "tweets")
では引数に指定した名前のクラスがParse上に存在すればそのオブジェクトを取得し、無ければ生成してくれます。
tweetsObject["name"] = name
では、作成したテーブルに name という名前のカラムを作成し、値を保存しています。
最後にsaveInBackgroundWithBlock()
メソッドによって、非同期でDBに値を保存します。
DBから値の取得
続いて、保存した値を取得しましょう。TweetManager.swiftのfetchTweets()
メソッドを編集します。
import UIKit
import Parse
class TweetManager: NSObject {
var tweets: Array<Tweet> = []
static let sharedInstance = TweetManager()
func fetchTweets(callback: () -> Void) {
let query = PFQuery(className: "tweets")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock { (tweets, error) -> Void in
if error == nil {
self.tweets = []
for tweet in tweets as! Array<PFObject> {
let name = tweet["name"] as! String
let text = tweet["text"] as! String
let tweet = Tweet(name: name, text: text)
self.tweets.append(tweet)
}
callback()
}
}
}
}
let query = PFQuery(className: "tweets")
DBから作成したオブジェクトを取得するためには、PFQueryを使用しています。
query.orderByDescending("createdAt")
取得した複数のオブジェクトを並び替えています。
findObjectsInBackgroundWithBlock()
メソッドにてDBから実際にツイートのデータを全て非同期で取得します。
後は取得すたツイートでデータを作成したTweetモデルに変換し、配列に保存しています。
Parse上で保存したデータの確認
ツイートしたデータを確認することができました。
次回予告
次回はParseを使ったログイン機能の実装を紹介しちゃうぞえ