一个组织良好的Objective-C网络交互库。
目前,GDXNet
只支持RESTful协议。套接字支持正在进行中,我正在努力。
让我们设想您想与一个具有API入口点URL http://myserver.com/api/
的RESTful后端服务器交互。此服务器仅接受一个符合以下规范的POST方法:
Name: getHistory
HTTP Method: POST
Response Type: JSON
从GDXNetPacket
类创建一个子类,命名为MyServerPacket
,并实现GDXRESTPacket
协议。这是我们API入口点类。接下来,为您的类设置以下属性:
@implementation MyServerPacket
- (instancetype)initWithJSON:(id)json {
return [super init]; // our root packet will not parse any input JSON
}
- (void)parseResponse:(id)response error:(NSError *)error {
// empty
}
- (NSString *)urlBase {
return @"http://myserver.com/api/";
}
- (NSString *)urlRelative {
NSAssert(0, nil); // root packet has no relative URL
return nil;
}
- (NSArray *)headers {
return @[]; // no headers by default
}
- (NSDictionary *)params {
return @{}; // no API method's input parameters by default
}
- (GDXRESTPacketType)type {
return GDXRESTPacketTypePOST; // for our server default HTTP method is POST
}
- (GDXRESTPacketOptions *)options {
GDXRESTPacketOptions *options = [GDXRESTPacketOptions new];
options.cacheAllowed = NO; // forbid cache
options.silent = NO; // silent requests, see 'GDXRESTPacketOptions' explanation below
options.repeatOnSuccess = NO; // should be auto-repeated on success
options.repeatOnFailure = NO; // should be auto-repeated on failure
options.timeout = 30; // request timeout
return options;
}
- (GDXRESTOperationType)requestType {
return GDXRESTOperationTypeHTTP; // default request type is HTTP
}
- (GDXRESTOperationType)responseType {
return GDXRESTOperationTypeHTTP; // default response type is HTTP
}
@end
现在我们应该处理我们单个API的方法。从您的MyServerPacket
类创建一个子类,命名为GetHistoryPacket
,并指定其属性如下:
@implementation GetHistoryPacket
- (void)parseResponse:(id)response error:(NSError *)error {
NSLog(@"Data received: %@", response);
}
- (NSString *)urlRelative {
return @"getHistory";
}
@end
现在,当然,我们需要一个模型类来管理我们的请求。从NSObject
创建一个名为MyServerEntry
的类,并描述如下:
@implementation MyServerEntry
- (instancetype)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(processContext:)
name:kGDXNetAdapterDidReceiveResponseNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)requestGetHistory {
[[GDXNet instance] send:[GetHistoryPacket new] userInfo:nil method:GDXNetSendMethodREST];
}
- (void)processContext:(NSNotification *)notification {
NSLog(@"Parsed context with packet inside: %@", (GDXNetContext *)notification.object);
}
就是这样。现在您可以使用您的入口点如下所示:
self.entry = [MyServerEntry new]; // strong property, for example
[entry requestGetHistory]; // you will see results in Xcode console output
在processContext:
方法中,您将接收到一个包含您解析过的数据包以及一组有用的支持属性的GDXNetContext
类的实例。
如果您想深入了解库的结构,请阅读以下文章。它描述了库中的所有类。
从GDXNetPacket
中派生子类为您提供数据包的唯一标识符。实现GDXRESTPacket
协议使您能够根据REST交互协议描述数据包。之后,您将能够通过GDXNetMethodREST
方法发送您的数据包,通过GDXNet
门面类的实例(见下面的描述)。
通过GDXNet
发送的所有数据包都有其自己的上下文,该上下文包含唯一的上下文ID(它不与数据包ID相关),可以使用此上下文子类封装的允许的数据包协议,允许您管理取消的请求的isCancelled
属性,以及用于您自己目的的userInfo
字典,当然,还有您的GDXNetPacket
子类实例。所有这些数据都放置在GDXNetContext
抽象封装类中。
您将拥有一份与 GDXNetContext
的某个具体子类的协议,该子类可为您提供额外的特定信息。目前只有一个具体的子类名为 GDXRESTContext
,用于 REST 协议。
一个抽象适配器,包含发送和取消您的数据包的方法。还管理数据包内部异步解析响应(如果您手动取消请求,则不会解析响应)。在成功或失败的请求之后,GDXNetAdapter
会发布一个通知,告知您请求已结束。请注意,已取消的请求将作为 失败的 请求传递。
您将使用 GDXRESTAdapter
的子类来与 REST 上下文交互。
具有两个以下方法的门面单例类
- (NSDictionary<NSNumber *, NSString *> *)send:(GDXNetPacket *)packet userInfo:(NSDictionary *)userInfo method:(GDXNetSendMethod)method;
- (void)cancelRequestByContextId:(NSString *)contextId;
您可以使用指定的发送方法(GDXNetSendMethod
只是一个位掩码枚举)发送您的数据包(您自定义类的子类,该类反过来又是一个从 GDXNetPacket
的具体子类派生的子类)。GDXNet
将根据指定的发送方法选择您的数据包的有效适配器,然后通过所有这些适配器发送您的数据包。就是这样。
此方法返回一个字典,包含一对对的集合:发送方法
(作为键)=> 上下文 ID
(作为值)。之后您可以使用收到的上下文 ID 取消您的请求。
如您所见,如果您的数据包实现了 GDXRESTPacket
协议,则可以使用 GDXNetSendMethodREST
方法发送。当您添加套接字支持时,您的数据包将能够实现套接字数据包协议,并使用套接字发送方法发送。您所有的网络交互都被分离到层中,您所有的数据包都是干净且独立的,所有的请求都有自己的中心入口点。简单明了。
您可以在 Samples
文件夹中找到示例项目。
Apache。详情请参阅 LICENSE
。