2009-07-17 32 views
8

我正在嘗試爲使用外部數據源的iPhone編寫核心數據應用程序。我沒有真正使用Core Data來堅持我的對象,而是用於對象生命週期管理。關於如何將本地數據用於核心數據,我有一個相當不錯的主意,但已經遇到了遠程數據的一些問題。我將以Flickr的API爲例。使用核心數據訪問遠程數據的模式?

第一件事是,如果我需要說,最近的照片列表,我需要從外部數據源抓住他們。我檢索完列表後,似乎應該爲每張照片迭代並創建託管對象。此時,我可以繼續使用我的代碼,並使用標準Core Data API設置提取請求並檢索關於狗的照片子集。

但是,如果我然後想要繼續並檢索用戶的照片列表呢?由於這兩個數據集可能會相交,因此我是否必須對現有數據執行獲取請求,更新現有數據,然後插入新對象?

-

在舊的模式,我只想對每個數據集的不同的數據結構,並適當地訪問它們。最近的照片集和和用戶照片集。但是因爲Core Data的一般模式似乎是使用一個託管對象上下文,所以我似乎(我可能錯了)必須將我的數據與主數據池合併。但是,這只是爲了獲取照片清單而花費很大的開銷。我應該爲不同的集合創建一個單獨的託管對象上下文嗎?核心數據是否應該在這裏使用?

我認爲我發現對Core Data有吸引力的是,之前(對於Web服務),我會對某些數據提出請求,並在請求中對其進行過濾,或者在代碼中對其進行過濾並生成一個我將使用的列表。使用核心數據,我可以獲取對象列表,將它們添加到我的池中(根據需要更新舊對象),然後對其進行查詢。然而,我可以用這種方法看到一個問題,如果對象被外部刪除,我不知道,因爲我保留了我的舊數據。

我的基地在這裏嗎?人們有沒有處理遠程數據和核心數據的模式? :)我發現有幾個人說他們已經做到了,而且這對他們來說很有用,但是卻很少有例子。謝謝。

+0

你能對你想要的更具體嗎? '使用外部數據源'非常模糊。這聽起來像你想在本地鏡像一個外部數據庫的一部分。你是否需要進行本地改變,以獲得提升?關於衝突呢?這是一個困難的問題,更多的細節將有助於建議方向。 – 2009-11-21 03:59:37

+0

也許是一個陳舊的線程,我會試圖在後臺線程中獲取東西,並將它們寫入永久存儲區,並讓通知從那裏到達主線程 - 不確定它會工作,但會很好如果它確實有 – bshirley 2011-06-02 01:46:05

回答

0

對於這樣的情況,您可以使用Cocoa的存檔工具在會話之間將照片對象(和索引)保存到磁盤,並在每次應用程序調用Flickr時將其全部覆蓋。

但是既然您已經在使用Core Data,並且像它提供的功能一樣,爲什麼不修改您的數據模型以包含「source」或「callType」屬性?目前,您隱式地創建了一系列源代碼爲「Flickr API」的對象,但您可以輕鬆地將不同的API調用視爲唯一的源,然後將其明確存儲。

要處理刪除操作,最簡單的方法是在每次刷新時清除數據存儲區。否則,您需要遍歷所有內容並僅刪除未包含在新結果中的文件名的照片對象。

我打算自己做一些類似的事情,所以我希望這有助於。 PS:如果你沒有在會話之間存儲照片對象,你可以使用兩個不同的上下文並分別查詢它們。只要他們從來沒有保存過,而且中央商店已經沒有任何東西了,它就會像你所描述的那樣工作。

2

在我看來,你的第一個直覺是正確的:你應該使用fetchrequests來更新你現有的商店。我用於導入器的方法如下:獲取有資格導入並存儲在某處的所有文件的列表。我在這裏假設獲得這個列表是快速和輕量級的(只是一個名稱和一個url或唯一的id),但是真正導入某些內容會花費更多的時間和精力,用戶可能會退出程序或想要做一些事情否則在所有導入完成之前。

然後,在一個單獨的後臺線程上(這並不像聽起來那麼困難,這要歸功於NSRunLoop和NSTimer,谷歌關於「核心數據:高效導入數據」),獲取該列表的第一項, Flickr或任何地方,並在Core Data數據庫中搜索它(仔細閱讀Apple有關設置高效,緩存的NSFetchRequest的Predicate Programming Guide)。如果遠程對象已存在於核心數據中,則根據需要更新信息,如果不插入。完成後,從待導入列表中刪除項目並轉到下一個項目。

至於在遠程存儲中已刪除的對象的問題,有兩種解決方案:週期性同步或懶惰,按需同步。從Flickr導入照片是否意味着導入原始的東西及其所有元數據(我不知道關於所有權的政策是什麼等),或者你只是想導入縮略圖和一些信息? 如果您在本地存儲所有內容,則可以每隔幾天或幾周進行一次檢查,以查看本地商店中的所有內容是否都是遠程顯示的:如果沒有,用戶可能會決定保留照片或將其刪除。 如果您只存儲縮略圖或預覽,則每次用戶想要查看完整圖像時都需要連接到Flickr。如果它已被刪除,則可以通知用戶並在本地刪除它,或將其標記爲不再可訪問。

2

你可能會嘗試兩種情況的組合。這個策略會爲你提供一個接口,讓你獲得兩次NSFetchRequest的結果:一次同步,一次數據從網絡加載。

  1. 創建您自己的 NSFetchRequest這需要結束時獲取額外的塊屬性 執行子類。 這是爲您的異步請求到網絡 。我們打電話給 吧FLRFetchRequest

  2. 創建一個類,你將這個請求傳遞給 這個請求。我們稱之爲 FLRPhotoManagerFLRPhotoManager具有基於該找取請求的方法executeFetchRequest:它接受FLRFetchRequest和的 實例...

    1. 隊列網絡請求並沿着保持取指令請求傳送到被再次處理當網絡請求是完了。
    2. 針對您的CoreData緩存執行提取請求並立即返回結果。
    3. 現在,當網絡請求完成時,用網絡數據更新核心數據緩存,再次對緩存運行取回請求,這一次,從FLRFetchRequest中取出塊並將此取回請求的結果傳遞到塊,完成第二階段。

這是我想出了最好的模式,但像你一樣,我很感興趣,其他的見解。