2014年7月16日 星期三
How to handle binary file by Parse's Cloud Code
最近在開發Side Project的時候,因為不預期有Server Team的support,所以就來玩玩Parse的Cloud Code,這個東西大概在一兩年前就有碰過一次,那個時候是上傳一些感測器的資料,如果超過某個Threshold就要寄送notification到device。
這次的則是用在交易管理,最棒的是Stripe已經是Cloud Code的其中一個module,所以整合的過程不算太複雜;比較麻煩的事,我們需要上傳一包binary到Parse的Storage,如果由Client直接Create Data Object的話,就可以用ParseFile的物件直接搞定,該死的事繞過Cloud Code,它的Input預期是個JSON,這時候就有幾種解法:
1. 把Binary用Base64 Encode後放進JSON,但超過30MB的JSON會不會有其他悲劇發生?!
2. 直接Client端用ParseFile存檔,JSON裡面放上傳成功的URL。因為Binary沒有跟任何一筆Data Object關連,所以從後台Clean Cache的時候(可能)就會清掉。
3. 同上的Idea,但把資料放到S3。一樣很難清掉沒有意義的資料,因為存檔的動作都是由Client進行。
4. 用Pointer!Create 另外一個Table(Class),Client先Create好一筆Data後,把Object Id傳給Server做關聯。
最後我們採用第四種做法,兼具consistance以及簡化的流程。但看了Parse的Free Plan,20GB的儲存空間,以我們的使用情境,大概1000筆訂單後就要開始付錢了:<
2014年7月7日 星期一
Retrofit : A type-safe REST client for Android and Java
Square 雖然是做支付的公司,但也open了許多好用的library,像是OkHttp、Picasso跟Otto等等;目前公司產品內有使用的是Otto,它解決了Activity跟Fragment,或者Fragment跟Fragment之間的雙向溝通(關於Otto改天再寫別篇文章來描述使用情境),而今天要介紹的Retrofit能簡化Client跟Server間的Code。
舉例說明,如果你要對Restful Server拿資料,首先你要開HttpClient,然後把Api的參數(POST/GET/PUT/DELETE以及Parameters)塞進去;因為Android不允許Http Connection跑在UI Thread,所以你必須在包一個AsyncTask;接著要Parsing Response Body,如果是JSON可以用內建的JOSN Library去一層一層get出來,聰明一點就會用Gson Library。對了你別忘記了Http還有很多複雜的情境,像是Response Code : 301/302的Redirect、Cache的功能、Retry的機制等等等等。
完整的程式片段可能會像這樣(別忘了,它還沒辦法handle 301/302、Cache跟Retry的機制):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
protected onCreate(Bundle savedStateInstance) { | |
NetworkTask task = new NetworkTask(this); | |
NetworkTask.execute(); | |
} | |
public void successful(List<Repo> repos) { | |
// do something | |
} | |
public void fail(Exception e) { | |
// do something | |
} | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class NetworkTask extends AsyncTask<Void, Void, String> { | |
private Callback callback; | |
public interface Callback { | |
public void successful(List<Repo> repos); | |
public void fail(Exception e); | |
} | |
public NetworkTask(Callback callback) { | |
this.callback = callback; | |
} | |
protected Void doInBackground (Void.. params) { | |
// we hard code here, because it should be re-design more interface if we want to support different type of parameter. | |
String url = "http://example.com/users/PRADA/repos?limit=10"; | |
HttpGet request = new HttpGet(url); | |
AndroidHttpClient client = AndroidHttpClient.newInstance("Android"); | |
try { | |
HttpResponse response = client.execute(request); | |
HttpEntity entity = response.getEntity(); | |
return EntityUtils.toString(entity); | |
} catch (Exception e) { | |
return null; | |
} finally { | |
client.close(); | |
} | |
} | |
protected void onPostExecute (String result) { | |
if (callback != null) { | |
if (result == null) { | |
callback.fail(new Exception()); | |
} else { | |
callback.successful(parseJsonString(result)); | |
} | |
} | |
} | |
private List<Repo> parseJsonString(String json) { | |
// TODO | |
} | |
} |
Retrofit能讓這一切簡單一些,讓您不再畏懼/厭煩對接所有Restful API,關於使用細節就直接參考官方文件。把同樣的程式用Retrofit再寫一次的結果如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
protected onCreate(Bundle savedStateInstance) { | |
RestAdapter restAdapter = new RestAdapter.Builder() | |
.setEndpoint("https://example.com") | |
.build(); | |
SampleService service = restAdapter.create(SampleService.class); | |
List<Repo> repos = service.listRepos("PRADA", 10); | |
} | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface SampleService | |
@GET("/users/{user}/repos") | |
List<Repo> listRepos(@Path("user") String user, @Query("limit") int limit); | |
} |
如果有任何問題,歡迎各位一起討論。
訂閱:
文章 (Atom)