一、為什么要封裝一下
AsyncSocket作為使用最多的長連接第三框架,相比于其他的網絡請求,雖然他封裝了socket,但是如果項目中每個頁面都涉及到網絡請求,代碼量還是很大的,所以就在把他封裝一下,使用單例調用,每個頁面調用接口就行了。
二、正文(此文以做登錄功能為例)
1、首先項目導入AsyncSocket的第三方框架文件
AsyncSocket.png
這兩個文件就不用我給傳送門了吧。。demo項目里也有,傳送門Github
2、建立單例類文件
單例類.png
3、SingletonSocket.h中導入AsyncSocket.h
設置相應屬性和方法,如圖:
SingletonSocket.h.png
4、SingletonSocket.m中
創建單例(這里只列舉一種創建單例的方法)
+ (SingletonSocket *)sharedInstance
{
static SingletonSocket *sharedInstace = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
sharedInstace = [[self alloc] init];
});
return sharedInstace;
}
* 這里就不每個方法的實現都解釋了,這里說一下發送和接收數據
發送數據
- (void)sendMessage:(id)message
{
//像服務器發送數據
NSData *cmdData = [message dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:cmdData withTimeout:-1 tag:1];
}
(id)message是即將給服務器發送的數據,比如登錄的時候,發送的數據包括用戶名和密碼,所以(id)message的類型由服務器指定,我們的項目是字典類型。
接收數據
//接受消息成功之后回調
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSLog(@"data is %@",data);
/*
1.data為接收到的數據
2.通過通知,block,代理等方法傳出去
*/
[self.socket readDataWithTimeout:-1 tag:0];
}
數據發送成功后會走接收數據的這個代理方法,data即為接收到的數據,當然他是在我們創建的單例類里接收到的,我們要用block或其他方法把data傳出去,供其他頁面解析。
5、具體調用
demo里是在viewConreoller.m里調用
首先
ViewController.m 中導入單例類
viewConreoller。m.png
然后
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//連接前,先手動斷開
[[SingletonSocket sharedInstance] cutOffSocket];
[SingletonSocket sharedInstance].socket.userData = SocketOfflineByServer;
[[SingletonSocket sharedInstance] startConnectSocket];
/*
1. 向服務器發送信息,例如:登錄指令的data數據
2.登錄成功后,這里可以通過通知,block,代理接收到 SingletonSoket.m 中接收到的數據進行解析
*/
[[SingletonSocket sharedInstance] sendMessage:@"login"];
}
如果[[SingletonSocket sharedInstance] sendMessage:@"login"]數據發送成功,我們就可以把單例類里接收到的數據傳過來解析了,實現后面的功能。
demo地址:Github
** Tips**
- 如果你要接受的數據比較大的話,接受數據的方法是分包接收的,容易產生粘包現象,此時要設置數據頭和尾的標識,分包接收直到接收到標示尾。
- 如果你用字符串或其它類型接收數據,初始化要寫在接受數據方法的外面,防止粘包。
如果有寫的不對的地方,歡迎指出,我不完美,但我在努力。