领域初始化后从未调用过领域通知

时间:2016-10-18 13:30:10

标签: ios swift realm

我有一个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方法。 任何暗示都会受到欢迎

1 个答案:

答案 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。这意味着它将始终添加(并且永不更新),即使对象存在相同的主键。