IMSDK封裝<三>

xiaobaicai發表於2016-03-07

XMPP Framework是一個百寶箱,Robbie Hanson 是一個怪獸級別的程式設計師。

訊息與業務物件的互相轉化是一個累活

我們基於XMPP Framework做業務封裝,我們必須要處理業務物件和訊息的互相轉化。我們自定義的協議為每一種訊息擴充了不同的節點(XML),這其中,有兩種訊息我們共用一個節點,因此,這個節點裡的資訊的差異,我們都要解析,另外在單聊和群聊的基礎上我們還劃分了一個討論組型別,but 這個討論組型別並不像chat和groupchat那麼容易得到,它又隱藏在一個單獨的擴充節點裡面用bool值去區分,因此這種轉化是一個疲累的活。

讓我們學習Robbie Hanson,如何處理累活

直接面對協議,一個節點一個節點的轉,是繁瑣不堪的。我們面對的問題是如何將我們自定義的協議,用oc物件的方式去處理。就像json轉model,熟以習常的面向模型去開發。其實這種思路轉換並不容易,程式設計師容易只見樹木不見森林,很難跳出自己的安全區。XMPP框架就是實現協議的程式碼,Robbie Hanson是一個傑出的程式設計師,讓我們學習他的處理方式。XMPP協議是基於XML格式便籤來傳遞資訊,在官方協議裡面最常見的是三個標籤節點,分別為<message></message>、<iq></iq>、<present></present> . Robbie Hanson針對這三種協議設計了三個類。我們可以在Framework的core找到。

XMPPElement XMPPMessage XMPPIQ XMPPPresent

其中XMPPElement是他們的基類。讓我們體會下面的這種對比。

<message type="chat" to="xiaoming@example.com">  
  <body>Hello World!<body />  
<message />  

讓我們來看結點的對應類的對映

@interface XMPPMessage XMPPElement  
...  
- (NSString *)type;  
- (NSString *)subject;  
- (NSString *)body;Hello World!  
- (NSString *)bodyForLanguage:(NSString *)language;  
- (NSString *)thread;  
...  
@end  

現在,我們獲取某個節點的值,完全是物件導向,雖然NSXMLElement也是物件,但是XMPPMessage更加面向模型。例如,獲取type、body,我們直接

message.type  或者 [message type]  
message.body 或者 [message body]

有了這樣的對比,我們頓時就清楚了。比如我們為我們的訊息型別擴充了一個location節點

 <location xmlns = “xxxx”>  
       <longitude> xxx </longitude>         
       <latitude>xxx </latitude>  
       <adress> xxx </adress>  
          ....  
 </location>  

那麼我們可以這樣用類來描述

@interface LocationElement : XMPPElement
@property (nonatomic, copy) NSString *longitude;
@property (nonatomic, copy) NSString *latitude;
@property (nonatomic, copy) NSString *city;
@end

即使我們自定義的節點,攜帶的資訊非常多,我們也可以從容的去處理。

最後我們為XMPPMessage類,增加了一個分類,方便從XMPPMessage獲取我們自定義的子節點

@interface XMPPMessage (SETransfer)
- (BOOL)isMessageWithFile;
- (FileInfoElement*)fileInfoElement;
....
- (BOOL)isMessageWithLocation;
- (LocationInfoElement*)locationInfoElement;
....
@end

當然,我們對業務物件,也做了類似的處理。這樣我們就比較容易的完成了訊息與業務物件互相轉化的累活。

補充: 我們運用runtime,動態的業務物件新增了方法。

相關文章