ページ

2016年10月13日木曜日

Realm mobile platform アプリ作成1 - iOS -


以前デモアプリを試して、サーバーと同期が取れている事を試してみました。 今回は実際にiOSアプリに組み込んでみたいと思います。

プロジェクト作成

今回はXcode8でプロジェクトを作成していきます。
Create a new Xcode project > iOS > 
Application > Single View Applicationを選択。
Product NameやOrganization Name等はお好みで。
LanguegeはSwift、DevicesはiPhoneを選択します。

Keychainを使用する為、Keychain SharingをONにします。
※「Capabilities」タブにあります

次に「General」タブのEmbedded Binariesに前回ダウンロードした
realm-mobile-platformフォルダ内の「SDKs」>「realm_cocoa_XXX」> 
「ios」>「swift-3.0」にある「Realm.framework」と「RealmSwift.framework」を
ドラッグ&ドロップします。

その際に「Copy Items if Needed」にチェックを入れます。

コピー後


モデルの作成

次に簡単なモデルを作成します。
ViewController.swiftに以下を追加します。
import RealmSwift

final class Item : Object {
    dynamic var id = 0
    dynamic var name = ""
}
モデルの作成はObjectクラスを継承したクラスを作成し、
メンバはdynamic varで宣言します。

ユーザーログイン

アプリ起動時にサーバーにログインする処理を追加します。
var realm: Realm!

func login() {
    // サーバーURLを指定
    let url = URL(string: "http://localhost:9080")
    // 登録済みのユーザーで認証します
    let credential = Credential.usernamePassword(
      username: "user@example.com", password: "xxxxxx", actions: [.useExistingAccount])
    User.authenticate(with: credential, server: url!, onCompletion: {user, error in
        if let _ = user {
            // ログイン成功時
            // sample/database : DBで言うスキーマみたいなもの
            let realmURL = URL(string: "realm://localhost:9080/sample/database")!
            let configuration = Realm.Configuration(syncConfiguration: (user!, realmURL))
            Realm.Configuration.defaultConfiguration = configuration
            // realmオブジェクトを取得
            self.realm = try! Realm()

        } else if let _ = error {
            // ログイン失敗
            print("login error \(error)")
        }
    })
}

override func viewDidLoad() {
    super.viewDidLoad()
    login()
}
ログイン成功時に取得したRealmオブジェクトを使って処理を行います。

アイテム追加

ストーリーボードでButtonとTextFieldを追加します。

Button押下時のアクションをonPushAddとしてViewController.swiftに
イベント追加します。また、TextFieldもnameFieldとして追加します。

追加したonPushAddを以下のように修正します。
var count: Int = 0

@IBAction func onPushAdd(_ sender: AnyObject) {
    // TextFieldから現在入力されているテキストを取得
    let name = self.nameField.text
    try! self.realm?.write {
        // RealmオブジェクトにてItemを追加
        count = count + 1
        let item = Item()
        item.id = count
        item.name = name!
        self.realm.add(item)
    }
}
ここまで出来たらサーバー側で反映されているか確認します。
Realm Object Serverを起動し、Realm Browser.appを立ち上げます。
サーバー接続後、Openできるスキーマが増えているかと思います。

ログイン時に設定したスキーマになります。
※スキーマという名前であってるか分かりませんが、便宜上そう読んでます。
接続後に起動したアプリ上でTextFieldに文字列を入力しAddを押すと
データが追加されてればOKです。
gif
今回修正したViewController.swiftはここで見れます。

2016年10月9日日曜日

新しい技術を学んでみる 7 - Realm Mobile Platform -


ついこの間発表されたRealm Mobile Platformを試してみたいと思います。

Realmとは?
SQLiteやCore Dataの代替となるモバイルのデータベース
Android、iOS両方で使える。

Realm Mobile Platformとは?
データベースに加え、リアルタイムの同期、コンフリクトの解決、
イベントハンドリングといったサーバサイドの機能をシームレスに統合したもの。
現在はJava、Objective-C、Swiftのみ対応。

環境準備


開発環境としてはMacOSで進めていきます。
MacOS以外ではLinuxでも使えるようです。
まずはここから一式をダウンロードします。

ダウンロードしたフォルダの中にstart-object-server.commandがあるので、
ダブルクリックしてRealm Object Serverを立ち上げます。
Server起動するとブラウザが立ち上がりAdminユーザー作成画面が表示されます。

e-mailとpasswordを入力しAdminユーザーを作成します。
セットアップが完了すると再度e-mailとpasswordを求められるので入力しLoginします。

ログイン後ダッシュボード画面が表示されればセットアップ完了です。

デモを試してみる


早速何か動かしてみたいので、チュートリアルにあるRealmTasksを
動かしてみたいと思います。
先ほどダウンロードしたrealm-mobile-platformフォルダ内に
RealmTasks.appがあるので起動してみます。

起動するとe-mailとpasswordを求められるので、
適当なユーザーを作成してログインします。(※ローカル内だけでのアカウントなので適当で)
次に「+」を押して新規タスクを作成してみます。
タスクは左にドラッグで削除、右にドラッグでタスク完了の操作ができます。

Realm Browser


デモアプリを起動している状態で、サーバーと同期が取れているか確認してみます。
realm-mobile-platformフォルダ内にあるRealm Browser.appを起動します。
起動したらConnect to Object Serverを押します。
Server URLとAdmin Access Tokenを入力する画面で
デフォルトの場合
  • Server URL
    realm://localhost:9080
  • Admin Access Token
    start-object-server.commandをダブルクリックした時コンソールに出力されているAdmin Access Token
を入力します。
Realm Object Serverに接続されたRealm Browserでは
デモアプリと同期しているのが分かります。
gif

使ってみて


今回はデモを動かしてみただけですが、色んな用途で使えそうです。
次は実際にアプリに組み込んで、組み込み易さを検証したいと思います。

また、今回はローカル内で完結していたのでレスポンスが早いのは当たり前ですが
実際のサーバー上とのやりとりでどんな感じが試してみたいと思います。


2016年10月2日日曜日

Reactを使う 5 - ログイン画面 -


今回は簡単なログイン画面を作ってみたいと思います。
の前に・・余談ですがエディッタにatomを使っている場合、
デフォルトだと.jsxファイルを開いてもシンタックスハイライトされていません。
そこでreactパッケージをインストールすると.jsxファイルが
シンタックスハイライトされて表示されるようになります。
本当にただの余談でしたw

コンポーネント作成

構成は今まで通りで、今回はlogin.jsxを新たに作成します。
まずは画面だけを作成します。login.jsxを次のように実装します。
import React from 'react';
import ReactDOM from 'react-dom'

class Login extends React.Component {

  constructor() {
    super();
    this.state = {
      msg: 'none'
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    console.log('handleSubmit');
  }

  render() {
    return (
      <div className="login">
        <h1>Login</h1>
        <form className="loing form" onSubmit={this.handleSubmit}>
          <input type="text" placeholder="Name" />
          <input type="text" placeholder="Password" />
          <input type="submit" value="Submit" />
        </form>
        <p>{this.state.msg}</p>
      </div>
    );
  }
}

ReactDOM.render(
  <Login />,
  document.getElementById('container')
);
↑でclassではなくclassNameとなっていますがclassと同じ働きをします。
また、↑ではSubmitボタンを押してもコンソールにログが出るだけになってます。
実行結果


イベント処理

次にSubmitボタンを押したら入力された名前とパスワードを
画面に表示させてみたいと思います。
まずはinputにrefを追加します。
  • refとは? ・・・ inputなどの要素にアクセスできるようにするもの
                              要素へアクセスするにはReactDOM.findDOMNodeを使う
という事で早速refを追加してみます。
<form className="loing form" onSubmit={this.handleSubmit}>
  <input type="text" placeholder="Name" ref={(ref) => this.inputName = ref} />
  <input type="text" placeholder="Password" ref={(ref) => this.inputPass = ref} />
  <input type="submit" value="Submit" />
</form>
コールバックとして受け取ったrefをthis.inputNameやthis.inputPassに設定しています。
次にhandleSubmitを次のように修正します。
handleSubmit(e) {
  e.preventDefault(); // デバッグ用

  let name = ReactDOM.findDOMNode(this.inputName).value.trim();
  let pass = ReactDOM.findDOMNode(this.inputPass).value.trim();
  let message = `name[${name}] pass[${pass}]`;

  this.setState({msg: message});
}
本来ならSubmitボタンが押されたらサーバー側で処理してログイン後の画面に
遷移したりするのですが、今回はデモの為イベントをpreventDefaultによって
止めています。
this.inputNameやthis.inputPassから値を取り出しメッセージを出力させています
実行するとinputに入力された内容が画面に表示されているかと思います。

スタイルシート適用

classNameで指定した部分にスタイルシートを適用させてみます。
と言っても普通のCSSと変わりないです。
.login {
  background: #e0ffff;
}

.form {
  background: #fff8dc;
}
背景色を変更。リロードすると以下のようになります。