俺の備忘録

趣味でITエンジニアをやってるものです

NiftyCloud mobile backend を使ってみた

来年の1月28日にParseがサービスを終了するらしいので、NiftyCloud mobile backend を使ってみることにしました。

まずは試しにツイッターみたいなアプリを作ってみようと思います。

環境

xcode7、swift2

機能

  • ユーザ登録
  • テキストを投稿
  • 投稿したテキストをタイムラインに表示

完成品はこんな感じです
f:id:daikon0413:20160309143002g:plain

手順

※NiftyColud mobile backend の導入は省きます

1 必要なパーツを配置

  • ログイン・会員登録を行うViewController
  • ユーザネームを表示するhomeViewController
  • タイムラインを表示するtimeLineViewController
  • ツイートを投稿するtweetViewController

それぞれのViewに設置したUIパーツは後述します。

f:id:daikon0413:20160309143447p:plain
ストーリーボードはこんな感じです。わかりにくくてすいません。

2 会員登録・ログイン・ログアウト機能を実装

storyboardのViewControllerに

  • ユーザネーム用のUITextField
  • パスワード用のUITextField
  • ログイン、会員登録ボタン

homeViewControllerに

  • ユーザネーム表示用のUILabal
  • ログアウトボタン

を設置します。

コードはこんな感じです。
ViewController.swift

import UIKit
import NCMB //NCMBフレームワークをインポート

class ViewController: UIViewController, UITextFieldDelegate {
    
    @IBOutlet var nameField: UITextField!
    @IBOutlet var passwardField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        nameField.delegate = self
        passwardField.delegate = self
        passwardField.secureTextEntry = true
    }

    //ユーザ登録
    @IBAction func signUp() {
        let user = NCMBUser()
        user.userName = nameField.text!
        user.password = passwardField.text!
        user.signUpInBackgroundWithBlock({(NSError error) in
            //ユーザ登録の処理
            if error != nil {
                //ユーザ登録に失敗
                print("error")
            } else {
                //ユーザ登録に成功
                self.dismissViewControllerAnimated(true, completion: nil)
            }
        })
    }
    
    //ログイン
    @IBAction func signIn() {
        NCMBUser.logInWithUsernameInBackground(emailField.text!, password: passwardField.text!,
            block: ({(NCMBUser user, NSError error) in
                //ログインの処理
                if error != nil {
                    //ログインに失敗した時
                    print(error)
                } else {
                    //ログインに成功した時
                    self.dismissViewControllerAnimated(true, completion: nil)
                }
        }))
    }
}

homeViewController.swift

import UIKit
import NCMB

class homeViewController: UIViewController {
    
    @IBOutlet var label: UILabel!

/*  省略  */
    
    override func viewDidAppear(animated: Bool) {
        if NCMBUser.currentUser() != nil {
            label.text = "ようこそ\(NCMBUser.currentUser().userName)さん"
        } else {
            let segueViewController: ViewController = self.storyboard?.instantiateViewControllerWithIdentifier("introView") as! ViewController
            self.presentViewController(segueViewController, animated: true, completion: nil)
        }
    }
    
    @IBAction func signOut() {
        NCMBUser.logOut()
        let segueViewController: ViewController = self.storyboard?.instantiateViewControllerWithIdentifier("introView") as! ViewController
        segueViewController.modalTransitionStyle = UIModalTransitionStyle.PartialCurl
        self.presentViewController(segueViewController, animated: true, completion: nil)
    }

}

3 タイムラインを実装

storyboardのtimeLineViewControllerに

  • UITableView
  • ツイート用のボタン

を設置。
ツイートボタンをtweetViewControllerにつなげる。

timeLineViewController.swift

import UIKit
import NCMB

class timeLineViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet var timeLineTable: UITableView!
    
    var tweets = [AnyObject]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        timeLineTable.delegate = self
        timeLineTable.dataSource = self
    }
    
    override func viewWillAppear(animated: Bool) {
        self.loadData()
    }
    
    //データの読み込み
    func loadData() {
        tweets.removeAll()
        let query = NCMBQuery(className: "Tweets")
        query.orderByDescending("createDate")
        query.findObjectsInBackgroundWithBlock({(NSArray objects, NSError error) in
            //データ読み込みの処理
            if error != nil {
                //読み込みに失敗したのとき
                print(error)
            } else {
                //読み込みに成功したとき
                if objects.count > 0 {
                    self.tweets = objects
                    self.timeLineTable.reloadData()
                }
            }
        })
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tweets.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
        
        cell.textLabel?.text = tweets[indexPath.row].objectForKey("tweet") as? String
        
        return cell
    }
    
    //セルの編集を許可
    func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }
    
    //セルが削除された時の処理
    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        let object = NCMBObject(className: "Tweets")
        object.objectId = tweets[indexPath.row].objectForKey("objectId") as? String
        object.fetchInBackgroundWithBlock({(NSError error) in
            //データの取得の処理
            if error != nil {
                //データの取得に失敗した時
                print(error)
            } else {
                //データの取得に成功した時の処理
                object.deleteInBackgroundWithBlock({(NSError error) in
                    //データの削除の処理
                    if error != nil {
                        //削除に失敗した時の処理
                        print(error)
                    } else {
                        //削除に成功した時の処理
                        self.loadData()
                        self.timeLineTable.reloadData()
                    }
                })
            }
        })
    }
}

ツイート機能を実装

storyboardのtweetViewControllerに

  • ツイート用のUITextView
  • 送信ボタン

を設置

tweetViewController.swift

import UIKit
import NCMB

class tweetViewController: UIViewController, UITextViewDelegate {
    
    @IBOutlet var tweetText: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tweetText.delegate = self
    }
    
    @IBAction func sendTweet() {
        let object = NCMBObject(className: "Tweets")
        object.setObject(tweetText.text!, forKey: "tweet")
        object.setObject(NCMBUser.currentUser().userName, forKey: "createdBy")
        object.saveInBackgroundWithBlock({(NSError error) in
            //データを保存
            if (error != nil) {
                //データの保存に失敗した時
                print(error)
            }else{
                //データの保存に成功した時
                self.navigationController?.popViewControllerAnimated(true)
            }
        })
    }
}

まだまだ手直しするところはありますが、ひとまずはこれで完成です。