文章よりも動画がお好きな方は、この記事は私が制作した動画の文章版です。 内容は同じです。
このビデオは、Siri ショートカット、CloudKit などの iOS フレームワークやツールの使用方法を教えるのに役立つと期待されるシリーズの最初のものです。 このシリーズで取り上げてほしい特定のフレームワークや機能がある場合は、jordanosterbergshadowsystemstech または Twitter の @josterbe1 までお気軽にご連絡ください。
目次
- はじめに
- 依存関係のインストール
- モデル
- Realm の実装
- まとめ
早速ですが、このシリーズで作るアプリケーションを見ていきましょう。…
Introduction
The list of notes, and when we tap into one, we can read and begin of editing, or delete it. とてもシンプルですね。 スターター プロジェクトをダウンロードすると、「Apple Park Visit」ノートをタップしたときに NoteDetailController に出入りしても、ノートが持続しないことに気がつくと思います。 つまり、メモを編集しても、メモの内容は保存されません。
この記事では、Realm Database を使用して、それを構築することになります。 私はちょうど 2 年ほど Realm を使用していますが、そのシンプルさは、サード パーティ製ライブラリを使用するコストよりも大きいと感じています。 実際、私が個人的に開発に最も時間を費やしているアプリ(https://countdowns.downloadを参照)では、macOS と iOS の両方で Realm を使用しています。
依存関係のインストール
Realm を使い始めるには、CocoaPods を使用してインストールする必要があります。 CocoaPods は、ご存じないかもしれませんが、iOS の領域で広く使用されている依存関係管理ツールです。 もしあなたのMacにまだCocoaPodsがインストールされていなければ、sudo gem install cocoapods
コマンドを使って始めることができます。
pod init
と入力し、open Podfile
と入力します。
新しく作成した「Podfile」の中に、プロジェクトにインストールしたいライブラリをCocoaPodsに通知するためのテキストを記述する必要があります。
# Pods for NotesApp
の下に、次の 2 行を記述します。
pod 'Realm', '~> 3.12.0'pod 'RealmSwift', '~> 3.12.0'
これらの行を記述した後のあなたの Podfile は、次のようなものになります。
platform :ios, '12.0'target 'NotesApp' do use_frameworks! # Pods for NotesApp pod 'Realm', '~> 3.12.0' pod 'RealmSwift', '~> 3.12.0' target 'NotesAppTests' do inherit! :search_paths end target 'NotesAppUITests' do inherit! :search_paths endend
さて、依存関係を追加したので、CocoaPods に pod install
でそれらをインストールするよう頼んでみましょう。 心配しないでください、CocoaPodsはいくつかの初期コンポーネントをダウンロードしているだけなのです。pod install
.
このコマンドが実行されると、あなたのターミナル・ウィンドウは次のようになります:
この後、NotesApp.xcodeproj
をすでに開いていたなら、それを閉じます。 CocoaPodsを使用する場合、デフォルトの.xcodeproj
ファイルではなく、.xcworkspace
ファイルを使用する必要があります。 NotesApp.xcworkspace
ファイルを開き、Note.swift
に向かいます。
The Model
このクラスには Note モデル オブジェクトが含まれており、いくつかの基本的なプロパティを含んでいます:
class Note { var identifier: String var content: String var lastEdited: Date init( identifier: String = UUID().uuidString, content: String, lastEdited: Date = Date()) { self.identifier = identifier self.content = content self.lastEdited = lastEdited }}
標準モデル コード、ここでは何も特別なことを行っているわけではありません。
また、同じファイルに Note オブジェクトの拡張機能があり、Writeable
extension Note: Writable { func write(dataSource: DataSource) { self.lastEdited = Date() dataSource.store(object: self) } func delete(dataSource: DataSource) { dataSource.delete(object: self) }}
というプロトコルとしてサブクラス化されています。DataSource
は、コードの上位レベルでデータをできるだけ抽象的に変更できるようにするためのジェネリック プロトコルです。 これは、私たちのプロジェクトではあまり頻繁に使用されていませんが、発展させて、格納できるオブジェクトについて異なる制約を持つ複数のデータソースを作成するためにさらに使用することが可能です。
私たちが store
または delete
オブジェクトを作成するときはいつでも、NotificationCenter
に対する次の呼び出しを使用します。
すべてのモデル ファイルとクラスが終わったので、Realm の実装を開始しましょう!
Realm の実装
Realm をプロジェクトに統合するには、3 つのステップがあります。
- Realm オブジェクトの作成
- Realm オブジェクトとプリミティブな Note オブジェクトをつなげる
- Realm でデータの取得と変更を始める
Realm オブジェクトの作成
このステップは比較的簡単です。 RealmNote.swift
という新しい Swift ファイルを作成しましょう。 RealmNote.swift
の内部で、RealmSwift フレームワークをインポートし、次のようなクラス宣言を作成します:
import RealmSwiftclass RealmNote: Object {}
Realm のデータベース関数で RealmNote
を使用できるようにするために Realm の Object
クラスをサブクラス化することにします。
次に、Note モデルにある 3 つのプロパティを追加します。
@objc dynamic var identifier: String = ""@objc dynamic var content: String = ""@objc dynamic var lastEdited: Date = Date()
変数宣言の @objc dynamic
部分で、プロパティを Objective-C に公開します。
クラスを仕上げるために、class func
primaryKey をオーバーライドし、オプションの文字列 (String?
) を値 “identifier” として返します。
これらのステップを完了すると、RealmNote
は次のようになります。
class RealmNote: Object { @objc dynamic var identifier: String = "" @objc dynamic var content: String = "" @objc dynamic var lastEdited: Date = Date() override class func primaryKey() -> String? { return "identifier" }}
ステップ1は以上です。 Note
と RealmNote
です。 RealmNote は Realm を扱うときに内部的に使用され、モデル層を UI から切り離すために使用されます。
RealmNote.swift
ファイルで、RealmNote
:
extension RealmNote {}
の拡張機能を作成します。
convenience init(note: Note) { self.init() self.identifier = note.identifier self.content = note.content self.lastEdited = note.lastEdited}
さて、RealmNote.swift
の仕上げとして、RealmNote
から初期化する Note
変数を拡張機能の中に作成します。
Note.swift
に移動して、ブリッジの残りの半分を記述します。 このコードは、本質的に RealmNote
の拡張機能と同じものです。
extension Note { convenience init(realmNote: RealmNote) { self.init(identifier: realmNote.identifier, content: realmNote.content, lastEdited: realmNote.lastEdited) } var realmNote: RealmNote { return RealmNote(note: self) }}
素晴らしい、これがステップ 2 です。 これで Note
から RealmNote
に、RealmNote
から Note
にアクセスできるようになりました。
Note(content: "Example").realmNote.note.realmNote.note.realmNote.note.realmNote// and so on...
Jokes aside, let’s finish our application with step three.
Begin the retrieving and modifying data with Realm
Head into NoteDataSource.swift
, and import RealmSwift
before the class declaration.This means that this code is completely valid:
さて、このように、は、の間に位置します。 Realm オブジェクトを変更、削除、取得する前に、Realm データベースのインスタンスが必要です。NoteDataSource
の init を次のように置き換えてください:
var realm: Realminit() { // Load our data self.realm = try! Realm()}
これで Realm データベースのインスタンスが作成されます。 実稼働環境では、インスタンスを作成するときに bang (!) 演算子を使いたくないでしょう。
次に、実際にオブジェクトをデータベースに格納するために store
関数を編集しましょう。 次のように記述します。
self.realm.add(note.realmNote, update: true)
これは、データベース内に新しい RealmNote
を作成するか、既存のものがあればそれを更新するものです。 これで完了です。 これで Realm データベースにオブジェクトが格納されました (ノートの書き込み関数の呼び出しは NoteDetailController.swift
で行われていますが、この書き込みを行うために実際に使用される関数を見たい場合は、
では、delete
関数を書いてみましょう。 ブリッジを記述した方法(Note
から RealmNote
を作成するたびに Realm を参照しない)のため、ノートの realmNote
プロパティではなく、ノートの識別子を使用してデータベースから直接オブジェクトをフェッチする必要があります。
これは簡単です。
if let realmNote = self.realm.object(ofType: RealmNote.self, forPrimaryKey: note.identifier) {}
これは Realm に、データベースから RealmNote
オブジェクトを、識別子または主キーとして note.identifier
を取得するように要求します。 なぜか、Realm で従来の write
関数を使用すると、アプリケーションがクラッシュします。 回避策として、このコードは完全に有効で、基本的に write
と同じタスクを実行します:
self.realm.beginWrite()self.realm.delete(realmNote)try? self.realm.commitWrite()
書き込みを開始し、オブジェクトを削除して、書き込みをコミットします。
これで、機能するノート アプリケーションが構築できました!
まとめ
この Realm Database を使うためのチュートリアルを楽しんでいただけるとうれしいです。 このシリーズを進化させ、Siri ショートカットや CloudKit などの機能をアプリに追加していくのが楽しみでなりません。 お読みいただきありがとうございました。