引言:
StackMob 是一個輕量級的 Baas 移動後端雲端儲存平台. 為移動App提供了強大的後台雲端儲存能力,其SDK架接在Core Data身上,在不改變Core
Data API 使用方式的前提下為Core Data 提供雲端儲存的能力,此篇專門介紹了 StackMob 在 iOS環境的使用方式.
參考資料:
1:StackMob 的首頁
https://www.stackmob.com/
2:StackMob iOS開發文檔
http://stackmob.github.io/stackmob-ios-sdk/
3:如何為iOS應用及遊戲添加後台網路服務系列1 前言
http://blog.sina.com.cn/s/blog_4b55f6860101b991.html
4:StackMob SDK 官方使用教程
https://developer.stackmob.com/tutorials/ios
5:16小時的誘惑大致的介紹了StackMob從註冊到使用的整個過程:
http://www.csdn.net/article/2013-03-19/2814542-build-an-airbnb-clone/1
安裝:
StackMob是開源的,託管地址如下:
https://github.com/stackmob/stackmob-ios-sdk
安裝的首先方式是CocoaPods.
可能遇到的問題:
1:解決AFNetworkKiting 安裝後警告部署問題,詳見這篇文章
2:解決 Reachability 類 的衝突問題,代碼如下:
3:讓 StackMob 串連至 Amazon S3 雲端儲存體服務
StackMob需要串連 Amazon S3 以後才擁有二進位檔案的儲存能力.
本篇博文大致的介紹了一下S3的註冊流程,可以稍作參考:
http://www.xieyidian.com/2692
第一步:前往亞馬遜Web Services 註冊一個開發人員帳號:
https://aws.amazon.com/cn/
第二步:註冊並啟用 S3
https://aws.amazon.com/cn/s3/
註冊並啟用S3需要一張支援外幣付費的信用卡,建議使用萬事達卡.
在索要卡片的介面填寫如下:
類型選擇:MasterCard
信用卡卡號
持卡人 拼音名稱. (按照信用卡上面填寫)
成功以後會計費一美元. 並收到開通S3服務的寄件提醒.
此時便已經開通了S3的服務,擁有了使用的權利,如果此時進入S3的控制台依舊提示你需要註冊的話,是瀏覽器緩衝的問題,清空即可.
第三步:進入 S3的管理主控台 建立一個 Bucket 如:
https://console.aws.amazon.com/s3
Region 選擇伺服器所在的國家,裡咱越緊越好. 日本吧
第四步:摘用StackMob官方的串連教程,基本上就搞定了:
http://developer.stackmob.com/tutorials/dashboard/Adding-a-Binary-Field-to-Schemas
在配置最後一步的連結時有一個欄位要特別注意,如所示:
那就是S3 Path Alias 這個欄位的值在設定不對的情況下去使用它產生的訪問連結,訪問的結果始終是中的錯誤:
如何才能正確設定S3 Path Alias?
首先要瞭解S3 Path Alias到底是做什麼用的,它一個連結地址別名
當我們用StackMob上傳一個二進位檔案成功以後,StackMob會自動根據S3 Path Alias所給定的值自動產生一個完整的二進位檔案下載連結.
如何檢驗這個下載連結的正確性,我們可以前往S3的控制台,隨便找一個已經上傳成功的檔案,查看其詳細資料,如所示:
拿圖中的Link和StackMob所產生的連結進行對比,看看有哪裡不一樣了. 如果不一樣,那麼S3 Path Alias的設定肯定有問題.
從來說,正確的S3 Path Alias設定方法應該是: http://s3-ap-northeast-1.amazonaws.com/musicpushtest/
最後S3的定價情況地址如下:(新使用者註冊免費12個月):
http://aws.amazon.com/cn/pricing/s3/
使用:
不足之處:
1:沒有二進位檔案上傳進度
原因:求解決
2:多次發起查詢請求和儲存請求,都有可能產生Crash,
原因: 由於線程調用錯亂 導致StackMob停止工作甚至Crash,使用前,請熟悉GCD,可以參考這篇教程. 這篇更全面
3:查詢和儲存請求發起後,無法立刻撤銷,必須等待整個請求完成
原因:求解決
4:分頁查詢起始索引預設必需設定值大於0 才有效果:
原因:我估計代碼內部BUG,注釋掉 判斷大於0 即可修正
5:查詢一對多的對象以後在緩衝到本地時,寫入指定Plist檔案時Crash
原因:NSDictionary的key 不是 NSString 所致, 修改了原始碼 替換索引值對的方法.
6:利用對象層級展開以後,卻無法擷取子物件資料
原因:求解決
功能要點:
一:關於二進位檔案上傳
1.設定Core Data 資料模型的欄位為字串類型.
2.手動設定StackMob 的 Schema 裡對應的欄位為二進位類型.
3.本機資料模型的欄位名稱和StackMob 的
Schema 的欄位名稱 關係如下:本地Core Data: userIcon Schema :user_icon
4.如果本地某個欄位 對應著伺服器的某個二進位欄位時,就在上傳伺服器時必須通過如下代碼賦值:
+ (NSString *)convertUploadWithPath:(NSString *)aPath withContentType:(NSString *)aContentType{ NSData *data = [NSData dataWithContentsOfFile:aPath]; if (data) { NSString *dataString = [SMBinaryDataConversion stringForBinaryData:data name:[aPath lastPathComponent] contentType:aContentType]; return dataString; }else { return @"file?"; }}
注:任何其他方式的賦值都不允許,否則會出現讓人無法理解的BUG.(特別注意)
上傳成功的二進位檔案欄位需要通過執行以下代碼才能擷取二進位檔案的下載連結
[[StackMobManager contextForCurrentThread] refreshObject:self.dmSongTyoe mergeChanges:YES];
但是這個只對新增的對象啟效果,如果你是更新對象使用上面的代碼重新整理的話,會變回你之前修改的值.那又怎麼解決呢?
二:資料緩衝機制
StackMob的緩衝機制預設是關閉的,如果要開啟,需要對以下全域變數賦值:
SM_CACHE_ENABLED = YES;
設定以後,StackMob會自動建立一個本地Core Data資料庫自動管理和緩衝來自伺服器的資料.
針對查詢資料機制有一個枚舉來決定其取數方式:
typedef enum { SMCachePolicyTryNetworkOnly = 0,//只從網路取 SMCachePolicyTryCacheOnly = 1, //只從緩衝取 SMCachePolicyTryNetworkElseCache = 2,//先從網路取,取不到用緩衝替代 SMCachePolicyTryCacheElseNetwork = 3,//這個還沒研究過} SMCachePolicy;
如果使用者更改了裝置的網路環境,可以通過以下Block去修改查詢資料機制:
SMClient *client = [[SMClient alloc] initWithAPIVersion:@"0" publicKey:@"XXXX"];SMCoreDataStore *coreDataStore = [client coreDataStoreWithManagedObjectModel:myModel];[client.session.networkMonitor setNetworkStatusChangeBlockWithCachePolicyReturn:^SMCachePolicy(SMNetworkStatus status) { if (status == Reachable) { return SMCachePolicyTryNetworkElseCache; } else { return SMCachePolicyTryCacheOnly; }}];
那麼在App啟動的時候,判斷一下當前的網路環境,設定好查詢資料機制:
if ([Reachability isEnable3G] || [Reachability isEnableWIFI]) { [self.keyCoreDataStore setCachePolicy:SMCachePolicyTryNetworkElseCache];}else{ [self.keyCoreDataStore setCachePolicy:SMCachePolicyTryCacheOnly];}
三:關於儲存(saveOnSuccess)
對Object的任何增刪改都通過saveOnSuccess 來保持雲端的資料同步.
用起來蠻簡單,不過也有些小細節要注意,否則也非常糾結.
1.saveOnSuccess因為一些網路原因或者儲存重複主鍵等問題導致儲存失敗,會進入失敗的Block.
如果連續進入三,四次左右的失敗Block,它~~~~~ 它~丫的~ App就Crash了. 臥槽... 什麼@try @catch 全都擋不住這個崩潰.
解決辦法是在失敗的Block裡面執行Core Data上下文刪除剛剛需要儲存的對象的操作.
[StackMobManager contextForCurrentThread] deleteObject:obj];
這樣不管你點多少次都不會Crash了,我覺得這是StackMob設計上的一些不足,不夠我也是菜鳥,不能夠做多評論.
2.Updating passwords via this API is disabled for security reasons. Use the resetPassword API instead
這個提示通過控制台列印過來,大意是說你當前的儲存資料請求被雲端給限制了.
我是怎麼觸發這個Error的?
當我發起建立一個新User對象的同時,再多儲存了一個File對象.File對象依賴於User對象,也就是說File對象的所有權是User對象的,但是你建立User對象的時候,你並沒有登入.
處於授權安全機制,本次儲存請求就算是失敗,(即使資料已經儲存到了雲端).
解決辦法是不要急著一起次儲存到雲端,只有等登入成功以後,再去發起File對象的儲存請求即可.
四:關於查詢(executeFetchRequest)
對Object的查詢就靠這個函數了,基本雷同CoreData的查詢函數,StackMob提供兩種發起查詢請求的方式.
一種是內部構建多線程運作工作,不會卡住主線程和影響介面,完成後通過主線程告知:
但是,連續多次發起這種請求方式, 有極高的幾率導致整個SDK停止工作. 這是個比較嚴重的問題,應該是StackMob 的BUG,
另外一種則是不構建多線程,如果直接執行,在沒返回結果之前會卡住主線程,影響介面體驗,但是我們可以自己使用GCD來避免主線程阻塞的這個問題
用這種方式似乎可以避免多次發起請求所產生的BUG,至少暫時沒發現.
在發起查詢請求之前有一個參數類要特別的注意一下,這個類也是實現個人化查詢的一個重要途徑之一,
它是SMRequestOptions
它有什麼用:
1:是否要求重新整理Token? tryRefreshToken
2:以HTPPS加密的方式安全擷取資料? isSecure
3:當請求網路逾時時,重試幾次呢? numberOfRetries
4:返回的資料結構需要展開幾個層次?(最多三級) setExpandDepth
5:只是想返回某幾個欄位的資料而已 restrictReturnedFieldsTo
總結: