2016-10-18 21 views
0

私はバックエンドからjsonを受け取って解析した後、私のUIを更新するUIViewを持っています。 一般的なAPIマネージャを使用しているため、コールバックの呼び出しが早すぎます。 私の回避策とベストプラクティスは、領域通知ブロックを使用することだと思います。 通知ブロックはviewDidLoadで一度呼び出されますが、jsonの解析後に領域オブジェクトプロパティを変更しても更新は呼び出されません。ビューのコードの サンプル:初期化後にレルム通知が呼び出されない

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 
    } 
} 

のようなボタンをタップした後、私は自分のレルムを更新するバックエンドにアクションを送る私の見解で:レルムオブジェクトの

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 
       } 
      } 
     } 

サンプルオブジェクトがfavoriteプロパティをtrueに設定します(trueの場合はfalse)。 realmオブジェクトのlikeプロパティが更新されたときに、通知ブロックがupdateViewメソッドを呼び出すことが予想されます。 どのようなヒントも大歓迎です

+0

ええ、何が起こっているのか分からずには分かりません。しかし、まず、レルム通知が実際に設定されているかどうかを確認します。あなたのコードは 'Article.getLocalArticle(article!.id)'から同じRealmオブジェクトを更新するバックエンドからJSONを解析するのですか? realm.write'ブロックにコードをラップするか、 'realm.commitWrite()'を使って書き込みをコミットすることで、realmオブジェクトへの更新を書いていますか? – KrispyDonuts

+0

サンプルを更新しました。 答えは両方の質問に対して「はい」です。 –

答えて

1

問題ありません。問題はどのようにオブジェクトをレルムに追加するかです。プライマリキーが存在する場合は、realm.add(article!, update: true)にのみupdateをtrueに設定できます。 updateプロパティは、realmに、主キーに基づいてRealmオブジェクトをインテリジェントに更新するように指示します(存在しない場合は追加するだけです)。

チェックこのアウト詳細は:あなたは、このエラーでrealm.add(article!, update:true)を行っているときレルムが例外をスローするため https://realm.io/docs/swift/latest/#creating-and-updating-objects-with-primary-keys


それは失敗だ理由は次のとおりです。

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です。つまり、同じプライマリキーを持つオブジェクトが存在する場合でも、常に追加され、更新されません。

+0

primaryKeyメソッドを追加しなかったのは、明らかに私が持っていたと思ったからです。あなたの答えに入れたものとまったく同じ私のコードのprimaryKeyメソッドでサンプルを更新しました。 私はIDの変数をサンプルに入れています。私のモデルには15個以上の変数があります。会社のコードなので、私が望むすべてを置くことはできません。誤解をおかけして申し訳ありません。 –

+1

心配はありません。私には分かりませんでした:)うーん、自分のマシン上でコードのバージョンをテストしただけで、Realmの通知が私のために働いています。あなたの 'id'が' article(json:JSON) 'で正しく解析されているかどうかを確認して、これが正しい結果を返すことを確認できますか?' Article.getLocalArticle(article!.id) '(記事を追加した後)。 – KrispyDonuts

+0

これはそうでなければ、Realmがスレッドを処理する方法と関係があるのだろうかと思います。しかし、スレッド間のすべてのRealmインスタンスは、実行ループのすべての書き込みまたは反復で同期/リフレッシュする必要があるため、この問題は予想されませんでした。 – KrispyDonuts

関連する問題