Swift,Objective-Cプログラミング ~ iOS ~

Objective-C,Swift,Apple Watchなどのプログラミング

【iOS Swift入門 #274】SwiftBondを使ってみる。MVVMをやる場合はこんな感じ?

SwiftBondとは

こちらを参照。
https://github.com/SwiftBond/Bond

この記事を読んでわかること

  • SwiftBondの導入方法
  • SwiftBondのちょっとした使い方
  • SwiftBondを使ったMVVM

SwiftBondの導入方法

SwiftBondの導入方法は4つ。

  1. Carthage
  2. CocoaPods
  3. git submodule
  4. SwiftBondのソースをプロジェクトに追加する

下記ではCarthageを使った導入方法をメモ。

Carthageを使って導入

Carthage自体はインストール済みの前提とする。

①ターミナルでプロジェクトのフォルダに移動し、下記コマンドを実行

touch Cartfile

②作成したCartfile内に下記を記述する

github "SwiftBond/Bond" ~> 4.0

③carthage updateコマンドでSwiftBondを取得

carthage update --platform iOS

④プロジェクトにSwiftBondのframeworkファイルを追加する
- frameworkファイルを追加 f:id:fjswkun:20160221121252p:plain

  • Build Phaseの設定に追加 f:id:fjswkun:20160221121313p:plain

  • Buildできるか確認

AppDelegateファイルに下記追加し、ビルドする。

import Bond

これまでの設定に問題がなければ、成功するはず。
問題なくビルドできたら、AppDelegateファイルに追加したimport分を削除する。

画面作成(SwiftBondを使う前の下準備)

①Storyboardにテキストフィールドとラベルを追加
f:id:fjswkun:20160221125622p:plain

②追加したテキストフィールドとラベルをソースにIBOutlet接続する

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

SwiftBondのちょっとした使い方

①キーボードでtextFieldに入力するとlabelの表示が変更されるようにする。
下記のとおりにソースを変更する。

textプロパティを追加しました。
これを使って、textFieldに入力したテキストをlabelに連携します。

textFieldのテキスト → textプロパティ → labelのテキスト

f:id:fjswkun:20160221130003p:plain

import UIKit
import Bond

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var label: UILabel!
    
    // 入力値保存用プロパティ
    var text = Observable<String?>("")

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // テキストフィールド入力値 → textプロパティ
        textField.bnd_text.bindTo(text)
        
        // テキストフィールド入力値 ↔ textプロパティ
        label.bnd_text.bidirectionalBindTo(text)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

②ビルドして確認 アプリ起動
f:id:fjswkun:20160221130320p:plain

テキストフィールドに入力
f:id:fjswkun:20160221130334p:plain

入力したテキストがラベルに表示される

__ テキストフィールドのテキストを消す f:id:fjswkun:20160221130346p:plain

ラベルの表示も変更される

SwiftBondを使ったMVVM

Personモデルを作りました。 nameプロパティとhobbyプロパティがあります。

アプリを起動すると下記画面が表示されます。
f:id:fjswkun:20160222171442p:plain

名前または趣味を入力すると
  View/ViewController → ViewModel → Personモデル と入力値が受け渡され、永続化されるようにしました。

画面
f:id:fjswkun:20160222170122p:plain

ViewController.swift

import UIKit
import Bond

class ViewController: UIViewController {
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var hobbyTextField: UITextField!
    private var viewModel = ViewModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewModel.name.bidirectionalBindTo(nameTextField.bnd_text)
        viewModel.hobby.bidirectionalBindTo(hobbyTextField.bnd_text)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

ViewModel

import Foundation
import Bond

struct ViewModel{
    var name = Observable<String?>("")
    var hobby = Observable<String?>("")
    private let person:Person

    init(){
        self.person = Person.loadPerson() ?? Person()
        self.name.value = self.person.name
        self.hobby.value = self.person.hobby
        
        // nameプロパティが更新されるとpersonを修正し、永続化
        name.observeNew{
            obj in
            
            if let text = obj{
                self.person.name = text
                self.person.update()
            }
        }

        // hobbyプロパティが更新されるとpersonを修正し、永続化
        hobby.observeNew{
            obj in
            if let text = obj{
                self.person.hobby = text
                self.person.update()
            }
        }
    }
}

Person

import UIKit

final class Person: NSObject,NSCoding {
    var name = ""
    var hobby = ""
    
    override init() {
        super.init()
    }
    
    internal func update(){
        let archive = NSKeyedArchiver.archivedDataWithRootObject(self)
        let userdefaults = NSUserDefaults.standardUserDefaults()
        userdefaults.setObject(archive, forKey: "Person")
    }
    
    class func loadPerson() -> Person?{
        let userdefaults = NSUserDefaults.standardUserDefaults()
        guard let unarchived = userdefaults.objectForKey("Person") as? NSData else{
            return Person()
        }
        
        return (NSKeyedUnarchiver.unarchiveObjectWithData(unarchived) as? Person) ?? Person()
    }
    
    // ユーザーデフォルトに保存するため
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(self.name, forKey: "name")
        aCoder.encodeObject(self.hobby, forKey: "hobby")
    }
    
    // ユーザーデフォルトに保存するため
    init?(coder aDecoder: NSCoder) {
        super.init()
        self.name = (aDecoder.decodeObjectForKey("name") as? String) ?? ""
        self.hobby = (aDecoder.decodeObjectForKey("hobby") as? String) ?? ""
    }
}

試す

①アプリ初回起動時 テキストフィールドは2つとも空です。 f:id:fjswkun:20160222170416p:plain

②名前と趣味を入力 f:id:fjswkun:20160222170423p:plain

③アプリを再起動
 ②で入力した名前と趣味が表示されます f:id:fjswkun:20160222170437p:plain

おわりに

サンプルソースを下記に格納しています。
SampleSwiftBond.zip - Google ドライブ


参考情報

Swift

iOSアプリ開発未経験の人向け
iOSアプリ開発をはじめたとき最初に買った書籍 【アプリ作成未経験の人向け】
Storyboardを使って画面を作成していく。
手順にしたがって操作していくと、ボタンの作成やWebViewの作成などができる。
アプリって、こんな感じで作るんだというのを体験できる。

Swiftではじめる iPhoneアプリ開発の教科書 【iOS 8&Xcode 6対応】

Swiftではじめる iPhoneアプリ開発の教科書 【iOS 8&Xcode 6対応】


・わかりやすくていい、と聞いた本
立ち読みした感じだと【アプリ作成未経験の人向け】

絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】

絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】


②を終えたくらいの知識の方向け
・アプリ開発独学中に2冊めに購入した書籍
プログラミング知識はなくても、若干理解するのに時間がかかる程度で、
読み進められるわかりやすさがある。

iPhoneアプリ開発塾

iPhoneアプリ開発塾


③中級者、上級者向け

詳解 Swift

詳解 Swift

詳解 Swift 改訂版

詳解 Swift 改訂版