前言
- 函數(shù)式+鏈?zhǔn)剑ㄒ?img class="math-inline" src="https://math.jianshu.com/math?formula=%5Ccolor%7Bred%7D%7BMasonry%7D" alt="\color{red}{Masonry}" mathimg="1">為例)
//例如
make.left.equalTo(self.view).offset(10)
//像這樣一直,把需要執(zhí)行的代碼一直寫下去,就可以稱為鏈?zhǔn)健?br> //像這樣
通過
去調(diào)用函數(shù),返回自身,可以簡單的理解為就是函數(shù)式。
- GCDAsyncSocket是一個(gè)寫的很好的Socket框架,但是感覺使用代理寫起來比較麻煩,另外基于學(xué)習(xí)函數(shù)式+鏈?zhǔn)骄幊?,所以順便簡單封裝一下GCDAsyncSocket庫。寫的不好的話,請大神指教。
進(jìn)入主題
-
項(xiàng)目大致結(jié)構(gòu)(還沒有包含GCDAsyncSocket所有功能,但我會持續(xù)研究)
image.png 首先 pod 'CocoaAsyncSocket'
主要的內(nèi)容(只貼.h文件,完整項(xiàng)目可以在本文最后調(diào)到Github下載)
//
// DVSocketManager.h
// DVSocketHelper
//
// Created by devil on 2019/6/24.
// Copyright ? 2019 devil. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "DVSocketConfig.h"
NS_ASSUME_NONNULL_BEGIN
//錯(cuò)誤回調(diào)
typedef void(^DVErrorCallBack)(DVActionCode code,NSString *msg);
//非錯(cuò)誤、讀取數(shù)據(jù)、寫數(shù)據(jù)之外的所有回調(diào)
typedef void(^DVActionCallBack)(DVActionCode code,id socketManager,_Nullable id result);
//讀取數(shù)據(jù)回調(diào)
typedef void(^DVReadDataCallBack)(DVActionCode code,id socketManager,NSUInteger partialLength,_Nullable id result,long tag);
//寫數(shù)據(jù)回調(diào)
typedef void(^DVWriteDataCallBack)(DVActionCode code,id socketManager,NSUInteger partialLength,NSUInteger totalLength,long tag);
@interface DVSocketManager : NSObject
+(DVSocketManager *(^)(void)) instance;
//當(dāng)前ClientSocket
-(id (^)(void)) currentClientSocket;
//設(shè)置連接地址和端口
-(DVSocketManager *(^)(NSString *address)) setAddress;
-(DVSocketManager *(^)(uint16_t port)) setPort;
//設(shè)置配置
-(DVSocketManager *(^)(DVSocketConfig *config)) setSocketConfig;
//編輯已有的配置
-(DVSocketManager *(^)(void(^editConfig)(DVSocketConfig *config))) editSocketConfig;
//設(shè)置錯(cuò)誤回調(diào)
-(DVSocketManager *(^)(DVErrorCallBack errorCallBack)) setErrorCallBack;
//設(shè)置非錯(cuò)誤回調(diào)
-(DVSocketManager *(^)(DVActionCallBack actionCallBack)) setActionCallBack;
//設(shè)置讀取數(shù)據(jù)回調(diào)
-(DVSocketManager *(^)(DVReadDataCallBack readDataCallBack)) setReadDataCallBack;
//設(shè)置寫數(shù)據(jù)回調(diào)
-(DVSocketManager *(^)(DVWriteDataCallBack writeDataCallBack)) setWriteDataCallBack;
//連接主機(jī)
-(DVSocketManager *(^)(void)) connect;
//作為主機(jī)監(jiān)聽端口
-(DVSocketManager *(^)(uint16_t port)) acceptOnPort;
//作為主機(jī)監(jiān)聽端口,端口為已設(shè)置的端口
-(DVSocketManager *(^)(void)) acceptOnCurrentSettingPort;
//作為主機(jī)監(jiān)聽端口
-(DVSocketManager *(^)(NSString *interface,uint16_t port)) acceptOnInterface;
//作為主機(jī)監(jiān)聽端口
-(DVSocketManager *(^)(NSURL *url,uint16_t port)) acceptOnUrl;
//讀取數(shù)據(jù)(一次)
-(DVSocketManager *(^)(long tag)) readData;
//設(shè)置每一次成功發(fā)送完數(shù)據(jù)之后都讀取數(shù)據(jù)
-(DVSocketManager *(^)(BOOL mark)) setReadDataWithAnySendData;
//寫數(shù)據(jù)(content為NSData時(shí)默認(rèn)為二進(jìn)制流)
-(DVSocketManager *(^)(id content,long tag)) writeData;
//寫文件數(shù)據(jù)
-(DVSocketManager *(^)(NSData *fileData,long tag)) writeFileWithData;
//寫文件數(shù)據(jù)
-(DVSocketManager *(^)(NSString *path,long tag)) writeFileWithPath;
//關(guān)閉連接
-(DVSocketManager *(^)(void)) closeConnection;
//是否已連接
-(BOOL (^)(void)) isConnected;
@end
NS_ASSUME_NONNULL_END
- 配置
//
// DVSocketConfig.h
// DVSocketHelper
//
// Created by devil on 2019/7/4.
// Copyright ? 2019 devil. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
//事件碼
typedef NS_ENUM(NSUInteger, DVActionCode) {
//DVErrorCallBack中回調(diào)
DV_OtherError = 0,//其它錯(cuò)誤
DV_ConnectTimeoutError = 1 << 0,//連接超時(shí)
DV_ConnectError = 1 << 1,//連接錯(cuò)誤或者斷開有錯(cuò)誤
DV_InputError = 1 << 2,//輸入數(shù)據(jù)錯(cuò)誤
DV_WriteDataError = 1 << 3,//寫數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤
//DVActionCallBack中回調(diào)
DV_Disconnect = 1 << 4,//正常手動斷開連接
DV_ConnectSuccess = 1 << 5,//連接成功
DV_StartConnect = 1 << 6,//開始連接
DV_DidReceiveTrust = 1 << 7,
DV_DocketDidSecure = 1 << 8,
DV_SocketDidCloseReadStream = 1 << 9,
DV_DidAcceptNewSocket = 1 << 10,
//DVWriteDataCallBack中回調(diào)
DV_WriteFileData = 1 << 11,//寫文件數(shù)據(jù)
DV_WriteFileDataSuccess = 1 << 12,//寫文件數(shù)據(jù)成功
DV_WriteOtherData = 1 << 13,//寫其它數(shù)據(jù)(字符串)
DV_WriteOtherDataSuccess = 1 << 14,//寫數(shù)據(jù)成功
//DVReadDataCallBack中回調(diào)
DV_ReadData = 1 << 15,//讀取數(shù)據(jù)
DV_ReadDataSuccess = 1 << 16//讀取數(shù)據(jù)成功
};
@interface DVSocketConfig : NSObject
//連接超時(shí)時(shí)間(默認(rèn)不限時(shí)-1)
@property (nonatomic,assign) NSTimeInterval connectTimeout;
//讀取數(shù)據(jù)超時(shí)時(shí)間(默認(rèn)不限時(shí)-1)
@property (nonatomic,assign) NSTimeInterval readDataTimeout;
//寫數(shù)據(jù)超時(shí)時(shí)間(默認(rèn)不限時(shí)-1)
@property (nonatomic,assign) NSTimeInterval writeDataTimeout;
//是否每次發(fā)送完數(shù)據(jù)之后都讀取數(shù)據(jù)(默認(rèn)NO)
@property (nonatomic,assign) BOOL isAfterAnySendDataToReadData;
//發(fā)送字符串?dāng)?shù)據(jù)的格式(每次發(fā)送都按照這個(gè)格式,只能包含一個(gè)%@,例如 @"||%@||",賦值時(shí)自動設(shè)置isOpenSendDataFormat為YES)
@property (nonatomic,copy) NSString *sendStringDataFormat;
//是否開啟發(fā)送數(shù)據(jù)使用特定格式(默認(rèn)不開啟)
@property (nonatomic,assign) BOOL isOpenSendStringDataFormat;
+(instancetype) defaultConfig;
@end
NS_ASSUME_NONNULL_END
- 使用
DVSocketManager.instance()
.setAddress(@"127.0.0.1")
.setPort(9999)
.setReadDataWithAnySendData(YES)
.editSocketConfig(^(DVSocketConfig *config){
config.sendStringDataFormat = @"||%@||";
})
.setErrorCallBack(^(DVActionCode code,NSString *msg){
NSLog(@"錯(cuò)誤-->code:%ld\tmsg:%@",(long)code,msg);
[self showMessage:msg];
})
.setActionCallBack(^(DVActionCode code,id socketManager,_Nullable id result){
NSLog(@"action-->%@",result);
if (code & DV_Disconnect) {
[self showMessage:@"斷開連接成功"];
}else if (code & DV_ConnectSuccess){
[self showMessage:@"連接成功"];
}
})
.setReadDataCallBack(^(DVActionCode code,id socketManager,NSUInteger partialLength,_Nullable id result,long tag){
if (code & DV_ReadDataSuccess) {
NSString *read = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
NSLog(@"read-->%@",read);
self.txt_readContent.text = [NSString stringWithFormat:@"%@\n服務(wù)器:%@",self.txt_readContent.text,read];
}
})
.setWriteDataCallBack(^(DVActionCode code,id socketManager,NSUInteger partialLength,NSUInteger totalLength,long tag){
if (code & DV_WriteFileData) {
NSLog(@"文件發(fā)送進(jìn)度-->%.2f",partialLength*1.0/totalLength);
}else if(code & DV_WriteFileDataSuccess){
NSLog(@"文件發(fā)送成功");
}else if(code & DV_WriteOtherDataSuccess){
NSLog(@"write-->code:%ld\tresult:%lu",(long)code,(unsigned long)totalLength);
NSString *text = self.txt_content.text;
self.txt_readContent.text = [NSString stringWithFormat:@"%@\n我:%@",self.txt_readContent.text,text];
self.txt_content.text = @"";
}
}).connect();
