WEBから取得したJSONデータを解析しRealmに取り込む
- iOS
-
2017-04-21 - 更新:2018-02-15
この記事は最終更新日から1年以上経過しています。
何やらタイトルが長くなってしまいましたが、複合的な内容なのでこうなりました。
今回やりたかったことはタイトルの通りですが、分解すると…
1)WEBからデータをダウンロード
2)バックグラウンドで処理を実行
3)JSONデータを解析
4)解析したデータをRealmに挿入
以上の4つです。
エラーが出なくなるまでかなり苦労したのですが、一番の原因は日本語の扱いに関する部分ですので、
日本語を含まないデータの解析だけならすんなり可能ではないかと思います。
1)WEBからデータをダウンロード
WEBからデータをダウンロードするにはURLSessionを使います。
ダウンロードするURLを指定
let url: String = "http://www.exam.jp/json.php"
セッションを作成します。
let session = URLSession(configuration: URLSessionConfiguration.default)
タスクを登録します。
let task = session.dataTask(with: URLRequest(url: Foundation.URL(string: url)!), completionHandler: {
(data, response, error) in
if let urlContent = data {
// ここに処理を記述
}
})
作成したタスクを実行します。
task.resume()
2)バックグラウンドで処理を実行
バックグラウンドで処理を実行するには、GCD(Grand Central Dispatch)を使用します。
DispatchQueue.global().async {
// バックグラウンドスレッドでの処理を記述
}
asyncだと非同期処理、syncだと同期処理になります。
3)JSONデータを解析
取得したJSONデータをJSONSerializationクラスを使って解析します。
let jsonObj = try! JSONSerialization.jsonObject(with: urlContent, options: [])
JSONデータが配列の場合は以下のようになります。
let list = try! JSONSerialization.jsonObject(with: urlContent, options: []) as! NSArray
4)解析したデータをRealmに挿入
解析したJSONデータをRealmデータベースに挿入します。
ここで注意点ですが、JSONの構造とRealmモデルの構造が同じである必要があります。
まずはRealmモデルを定義します。
class realmModel: Object {
dynamic var id = 0
dynamic var name = ""
// プライマリキーの定義
override class func primaryKey() -> String? {
return "id"
}
}
取得するJSONデータ
{ "id": 1, "name": "alpha" }
let realm = try! Realm()
do {
try realm.write {
let jsonObj = try! JSONSerialization.jsonObject(with: urlContent, options: [])
let myData = realmModel(value: jsonObj)
}
} catch {
}
JSONデータが配列の場合
取得するJSONデータ
[{ "id": 1, "name": "alpha" },{ "id": 2, "name": "beta" }]
try realm.write {
let list = try! JSONSerialization.jsonObject(with: urlContent, options: []) as! NSArray
for item in list {
let myData = realmModel(value: item)
print(myData) //デバッグ用に出力
realm.add(myData, update: true)
}
}
まとめると以下のようになります。
let url: String = "http://www.exam.jp/json.php"
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: URLRequest(url: Foundation.URL(string: url)!), completionHandler: {
(data, response, error) in
if let urlContent = data {
// バックグラウンドで処理を実行する。
DispatchQueue.global().async {
let realm = try! Realm()
do {
try realm.write {
let list = try! JSONSerialization.jsonObject(with: urlContent, options: []) as! NSArray
for item in list {
let myData = realmModel(value: item)
print(myData) //デバッグ用に出力
realm.add(myData, update: true)
}
}
} catch {
}
}
}
})
task.resume()
Xcode: 8.3.2
Swift: 3.1
OS: Sierra 10.12
この記事がお役に立ちましたらシェアお願いします
3,856 views




