LoginSignup
41
42

More than 5 years have passed since last update.

[Swift]Parseで簡単 DB連携でTwitter作成

Last updated at Posted at 2015-08-23

Parseとはなんぞや

バックエンドをswift(Obj-c)だけで簡単に実装できてしまうもの。

ここではざっくり説明していきます。
詳しくはParse iOS Guidをみて下さい。

ParseのDBの接続部分だけ見たい方は目次の[ParseDB連携]で飛んで下さい。

作成するアプリ

Twitterのようなアプリを作成しながら、Parseのありがたさを見ていきます。
メインはParseで用意されているDB(データベース)に保存するところですね。

名称未設定.png

Parse.comに新規登録

まずは、Parse.comに登録します。

登録完了したら、ホーム画面の右上の『Go to your apps』をクリック。

Parse_と_Parseを使ってみよう.png


次の画面では、Parse上にアプリ新しく作ります。その時に、アプリ名を設定します。

Home___Parse.png


作成されたアプリをクリックすると...

Home___Parse.png


アプリの管理ページが登場

Analytics___Parse.png

ここのページで保存したデータなどを確認するわけですねえ。

ここまでで、一旦Parse側の操作は終わりです。

Xcode側で新規プロジェクトを作成

いつものように、Xcodeのプロジェクトを作ります。

SDKのインポート

作成したプロジェクトにParseに用意されている、SDKをインポートします。

Prase.comに戻り、アプリ管理ページの下部の[Downloads]をクリック

Analytics___Parse.png


SDKをクリックすると、SDKをダウンロードすることができます。

Downloads___Changelogs___Parse.png


ダウンロードした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

Edit_Your_App___Parse.png

  • Application ID
  • Client Key

この2つを使用します。

Xcodeプロジェクト

AppDelegate.swiftに以下のように編集します。

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上はざっくりこんな感じです。

Main_storyboard_と_PracticeParseLogin_xcodeproj.png


必要なファイルを作成します。

  • Models
    • Tweet.swift(NSObject)
    • TweetManager.swift(NSObject)
  • Views
    • TweetTableViewCell.swift(UITableViewCell)
    • TweetTableViewCell.xib
  • ViewControllers
    • TweetsTableViewController.swift(UITableViewController)
    • NewTweetViewController.swfit(UIViewController)


今回は、Parseで用意さえたDBとの接続がメインなので、それ以外の部分はざざざっと書いていきます。

Tweet.swft
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に保存する処理を書く
    }
}
TweetManager.swift
import UIKit
import Parse

class TweetManager: NSObject {

    var tweets: Array<Tweet> = []
    static let sharedInstance = TweetManager()

    func fetchTweets(callback: () -> Void) {
        //後ほどParseのdbからツイート情報を取得する処理を記述    
    }
}

TweetTableViewCell.swift
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
    }
}

NewTweetViewController.swift
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()を編集していきます。

Tweet.swft
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()メソッドを編集します。

TweetManager.swift
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上で保存したデータの確認

Banners_and_Alerts_と_tweets___Parse.png

ツイートしたデータを確認することができました。


次回予告

次回はParseを使ったログイン機能の実装を紹介しちゃうぞえ

41
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
42