一、原生应用开发
如果需要开发原生应用并集成到C端 APP 中使用时,可以通过自定义服务实现该功能。C端 APP 基于 XMAF 服务框架使用,所以将自定义的服务注册到 XMAF 框架后,在C端 APP 中可以通过服务间的通讯与操作完成功能的调用。
下面通过一个简单的示例来表示自定义服务如何实现及使用。详细的说明请参考下文。大概流程是:
- 服务开发者创建自定义服务
- 应用开发者集成并注册服务
- 应用开发者调用相应的服务
注意自定义服务的创建人员是服务提供者,集成到应用中并使用该服务功能的人员是服务调用者,两者的身份是不同的,可以是同一开发人员,也可以是不同的开发人员。
1、创建自定义服务
自定义服务是由服务提供者创建的。
1.1、实现 XIServer 接口
所有的服务都需要实现 XFIServer 的接口。服务有自己的生命周期,由服务管理模块进行调度与处理。
实现上可以声明为XFIServer的Protocol。
@interface XFCustomServer : NSObject <XFIServer>
@end
@implementation XFCustomServer
+ (nonnull NSString *)getId {
return @"XFCustomServer";
}
- (BOOL)invokeServer:(nonnull NSString *)router params:(nonnull NSDictionary *)params callback:(nonnull XFMAResultDictErrorBlock)callback{
if ([self isSupportRouter:router]) {
NSString *url = params[@"url"];
NSString *formParameter = params[@"formParameter"];
NSDictionary *extendParameter = params[@"extendParameter"];
[self handleDataWithUrl:url formParameter:params extendParameter:extendParameter];
if (callback) {
callback(nil,nil);
}
return YES;
}
return NO;
}
- (void)handleDataWithUrl:(NSString *)url formParameter:(NSString *)formParamStr extendParameter:(NSDictionary *)extendParameter{
// 处理
}
- (BOOL)isSupportRouter:(nonnull NSString *)router {
if ([router isEqualToString:XFH5ServerRouterAppH5]) {
return YES;
}
return NO;
}
#pragma mark - XFIServerLifeCycle
- (void)onInit:(NSDictionary *)params {
NSLog(@"[%@] onInit",[[self class] getId]);
}
- (void)onRunning:(NSDictionary *)params {
NSLog(@"[%@] onRunning",[[self class] getId]);
}
- (void)onRegister:(NSDictionary *)params {
NSLog(@"[%@] onRegister",[[self class] getId]);
}
- (void)onUnRegister:(NSDictionary *)params {
NSLog(@"[%@] onUnRegister",[[self class] getId]);
}
- (void)onDestory:(NSDictionary *)params {
NSLog(@"[%@] onDestory",[[self class] getId]);
}
@end
1.2、定义服务功能
每个服务都可以有自己单独的功能,功能以普通的实例方法提供。
@interface XFCustomServer : NSObject <XFIServer>
//...省略上述创建的内容
//创建的实例方法,用于显性调用
- (void)customFunction;
@end
tips:某些场景可能需要使用到C端 APP 中的基础信息,如用户授权信息,用户数据等,请参考C端 APP 提供的基础服务。
1.3、确认服务提供的调用方式
在APP SDK的使用中,提及了服务的调用方式有两种,显式调用与隐式调用。在定义了服务的功能方法之后,服务就可以满足显式调用的方式使用了。
但是如果需要服务支持隐式调用,则需要实现服务的路由功能,否则无法完成服务的隐式调用。实现服务的路由功能时,需要实现服务接口中路由相关的方法。
1.3.1、定义路由功能
定义当前服务需要提供的功能以隐式方式提供时,使用的路由信息。调用者将通过该路由信息对相应的功能准确地调用。
//定义路由的功能,此处为登录页面的跳转
NSString * const XFCustomServerCustomFunctionPath = @"/XFCustomServer/customFunction";
1.3.2、实现路由功能的支持与处理
确定了路由信息后,需要实现与路由相关的方法,用于实现路由的功能处理。本质上相当于通过约定类似于 API 的访问方式,以指定的路由信息访问相关的功能或资源,并且返回操作的结果。
请注意所有的服务隐式调用时,返回的结果都是异步操作对象 XFAsyncAction。
@implementation XFCustomServer
//...省略上述创建的内容
//判断外部需要调用的路由是否匹配,当前服务是否支持该路由功能
- (BOOL)isSupportRouter:(nonnull NSString *)router {
if ([router isEqualToString:XFCustomServerCustomFunctionPath]) {
return YES;
}
return NO;
}
//处理路由功能
- (BOOL)invokeServer:(nonnull NSString *)router params:(nonnull NSDictionary *)params callback:(nonnull XFMAResultDictErrorBlock)callback{
if ([self isSupportRouter:router]) {
if ([router isEqualToString:XFCustomServerCustomFunctionPath]) {
// 处理自定义函数
}
}
return NO;
}
@end
2、注册服务
在服务创建成功后,需要注册服务到 XMAF 服务框架中,否则其它开发者无法通过 XMAF 访问并使用该服务。注册并使用服务是由服务调用者完成的。
tips:服务注册是由外部应用完成的,服务本身无法完成服务的注册。一般需要在应用初始化或在使用此服务前,显式地将服务注册到 XMAF 中,后续才能使用该服务。
服务的注册可以分两个不同的时机,在服务初始化时注册;或者是在使用该服务前再进行注册使用。两种方式都是允许的。
2.1、初始化时自动注册服务
//初始化时注册自定义服务
[XFUnionKit autoInit];
如果需要在初始化时自定义服务,需要在xlink_config.xf
文件中加入以该服务的serverId为key,如果需要在初始化时传入一些参数,可以将参数放置在value。示例如下:
"XFCustomServer":{
"custom_key1":"custom_value1",
"custom_key2":"custom_value2"
}
2.2、手动注册服务
如果没有定义在xlink_config.xf
文件中,则需要手动进行服务注册。
在任何时候,如果服务未注册时,都可以在使用前再进行注册并使用。
//注册并初始化返回该服务
[[XFServerManager shareInstance] registerServer:[XFCustomServer new]];
3、服务调用
服务的调用与开发指南中的服务调用一致。主要有两种方式,其中隐式的调用方式由服务提供方决定是否支持。在需要进行模块依赖的解耦与功能模块化时,推荐实现并使用隐式服务,调用者不需要关心具体的服务由谁提供,仅需要提前约定好使用的服务ID,路由信息及参数即可,在约定的规范不变的情况下,服务的提供方可以进行任何的更换。
3.1、显式调用
// 明确知道服务是 XFAuthServer 类型,并直接调用其中的方法,同时也必须在编译时依赖该服务
XFAuthServer *authServer = [[XFServerManager shareInstance] getServer:@"XFAuthServer"];
// 明确知道服务是有该方法
[authServer authThirdPartWithOpenId:openId accessToken:accessToken nickName:nickName resource:resource callback:^(NSDictionary * _Nullable result, NSError * _Nullable error) {
if (error) {
//登录失败
} else {
//登录成功后的 xlink 用户 token 信息
NSDictionary *userInfo = result;
}
}];
3.2、隐式调用
[XFServerManager createInvokeBuilder:^(XFServerInovkeBuilder * _Nonnull builder) {
//指定调用的服务ID
builder.serverId = @"A";
//指定调用的服务路由
builder.routerPath = @"B";
//配置服务使用的参数,这里参数的类型和数值需要和服务提供者确认。
builder.param = @"context"
} invokeServerWithCallback:^(NSDictionary * _Nullable result, NSError * _Nullable error) {
//调用服务返回的数据。
}];