我有一个UIView,我想在收到后更新我的ui并从后端解析json。 我使用通用API管理器,因此我的回调过早被调用。 我的解决方法和最佳实践我认为是使用领域通知块。 在viewDidLoad上调用通知块一次,但即使我在解析json之后修改了realm对象属性,也不会调用更新。 视图代码示例:
import SwiftyJson
import RealmSwift
var notificationToken: NotificationToken?
var article: Article?
if let result = Article.getLocalArticle(article!.id) {
// Observe Notifications on article from Network
notificationToken = result.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
switch changes {
case .Initial:
break
case .Update:
print("updating")
self!.updateView()
case .Error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError("\(error)")
break
}
}
}
领域对象的示例:
import SwiftyJson
import RealmSwift
public class Article : Object {
dynamic var liked = false
dynamic var id = String()
override public static func primaryKey() -> String? {
return "id"
}
// MARK: – Create article method
public class func article(json: JSON) -> Article? {
let article = Article()
if let id = json["id"].string {
article.id = id
}
if let liked = json["liked"].bool {
article.liked = liked
}
return article
}
// parse response Json for only one article after getting articleDetail
public class func parseUpdateArticleJson(json: JSON) {
//print(json)
do {
let realm = try Realm()
realm.beginWrite()
let article = self.article(json)
realm.add(article!, update: true)
try realm.commitWrite()
} catch {
print(error)
}
}
public class func getLocalArticle(articleId: String) -> Results<Article>? {
do {
let realm = try Realm()
let result = realm.objects(Article.self).filter("id == %@", articleId)
return result
} catch {
print(error)
}
return nil
}
}
在我的视图中点击like按钮后,我将动作发送到后端,后端将更新我的领域对象,将likes属性设置为true(如果为true则为false)。 预期的行为是通知块在更新mym对象上的like属性时调用updateView方法。 任何暗示都会受到欢迎
答案 0 :(得分:1)
好的,问题是你如何将对象添加到Realm。当主键存在时,您只能在update
中将realm.add(article!, update: true)
设置为true。 update属性告诉realm根据它的主键智能地更新Realm对象(或者如果它不存在则添加它)。
查看此信息以获取更多信息: https://realm.io/docs/swift/latest/#creating-and-updating-objects-with-primary-keys
它失败的原因是因为当您使用此错误执行realm.add(article!, update:true)
时,Realm会抛出异常:
Terminating app due to uncaught exception 'RLMException', reason: ''Article' does not have a primary key and can not be updated'
你的do / catch块捕获错误。该对象永远不会被添加到领域,并且通知块永远不会得到通知。这是我现在的假设,为什么它失败了。但是,我看到你正在打印错误,所以也许你已经抓住了这个。
所以你可以做的是通过这样做为你的Article对象分配一个主键:
public class Article : Object {
dynamic var liked = false
dynamic var id = String()
override static func primaryKey() -> String? {
return "id"
}
}
或者,如果您不希望id
属性成为主键(即唯一),则可以通过执行以下操作添加对象:realm.add(article)
。 update的默认值为false。这意味着它将始终添加(并且永不更新),即使对象存在相同的主键。