2017-08-08 90 views
0

經過淘汰the documentation後,我最近得知共享領域(全局可用於我的應用程序的所有用戶)只能用Realm.asyncOpen查詢。例如,我有一個/shared領域,它對任何用戶都具有隻讀權限。我試圖以通常的方式查詢它,但它返回了零個對象。但是,如果我查詢它這個樣子,它的工作原理:對象如何在Swift中的共享領域中同步

Realm.asyncOpen(configuration: sharedConfig) { realm, error in 
    if let realm = realm { 
    // Realm successfully opened 
    self.announcements = realm.objects(Announcement.self) 

    print(self.announcements) 
    self.tableView.reloadData() 

    } else if let error = error { 
    print(error) 
    } 
} 

這種方法明顯比通常的境界查詢速度較慢,因爲它似乎是從服務器,而不是本地,已同步境界獲取數據。

這是否意味着拉下來的對象永遠不會存儲在本地的副本中,而是每次訪問時都從ROS中查詢?

換句話說,共享領域拉和未同步?

回答

1

共享領域(在全球範圍提供給我的應用程序的所有用戶)只能與Realm.asyncOpen

質疑這是不正確。如果用戶只有只讀訪問領域,它必須與Realm.asyncOpen獲得。這是明確的什麼documentation you linked to states

這種方法明顯比通常的領域查詢要慢,因爲它似乎是從服務器取代數據而不是本地的,已經同步的領域。

幾乎正確。是從服務器獲取數據,但不是從頭開始的全部數據。只有自上次Realm與本地副本同步以來的新數據。

這是否意味着拉下來的對象永遠不會存儲在領域的本地副本中,而是每次訪問時都從ROS中查詢?

這個同步的Realm在本地保存,並將在應用程序啓動時保留。

換句話說,是共享領域拉和不同步?


退一步,讓我們解釋這裏發生了什麼。

如果您嘗試同步打開只讀同步的Realm,則會出現「權限被拒絕」錯誤的原因是初始化後,將創建本地Realm文件,執行寫入操作以寫入Realm架構(即立即創建數據庫表,列&元數據)。但是,由於用戶沒有對Realm的寫入權限,因此Realm對象服務器(ROS)會拒絕更改並觸發全局錯誤處理程序通知您用戶已修改文件的非法嘗試。

爲什麼這不符合asyncOpen發生的原因是,它是一個異步操作,因此不需要給你一個有效的境界立即,所以它並不需要通過編寫「引導」它架構。相反,它會從ROS請求最新的Realm狀態,並在該呼叫開始時的最新狀態完全可用時將其發回給您。這就是說,如果Realm的本地副本已經初始化其架構(即成功調用asyncOpen後),並且由默認架構定義的內存架構或Realm.Configuration中指定的定製對象類型hasn沒有改變,那麼就不會試圖將模式寫入文件。

這意味着任何時候調用asyncOpen成功後,只要沒有遇到可能沒有來自ROS的最新數據,就可以同步訪問Realm,而無需通過asyncOpen

所以在你的情況下,它看起來好像你只想用asyncOpen來第一次訪問Realm,所以你可以堅持這個狀態(使用另一個Realm或NSUserDefaults)並檢查它是否或不要異步或同步打開Realm。

+0

很好的答案,謝謝。那麼,我可以通過將領域全局寫入來解決整個問題嗎?我並不擔心這個問題的安全性,因爲我的應用程序不會提供任何寫入領域的機制。 –

+0

是的,如果Realm是全局可寫的,你就不會有這個問題,但我想認爲我所概述的解決方案不會犧牲訪問控制模型那麼麻煩,但那是你的呼叫。 – jpsim

+0

嗯......你是說你在用'asyncOpen'初始化'/ shared'領域後,我仍然可以用'NotificationToken'來監聽更改,並像任何普通領域一樣進行交互?我只需要'asyncOpen'來獲取模式更改? –