Skip to content

iOS APP集成

一、SDK 使用流程介绍

SDK 的使用流程如下:

  1. SDK 依赖并集成
  2. SDK 初始化
  3. 调用 SDK 进行第三方账号登录
  4. 根据业务需求使用相应的功能

二、SDK 集成

SDK 集成需要完成相关依赖库的集成操作。 iOS 的集成建议使用 Cocoapods 本地库的方式提供。另外有部分公共依赖库需要引用我们提供的远程库。

1、集成环境

环境要求
支持最低SDK版本iOS 10.0系统

2、配置依赖库

2.1、配置 Cocoapods 仓库

  1. 添加远程库配置

在项目下的Podfile文件中,添加上依赖库相关的的远程库 pod 源。

bash
# CocoaPods 官方 Specs
source "https://github.com/CocoaPods/Specs.git"
# XLink 容器 Specs
source "https://code.xlink.cn/sdkLib/Specs.git"
  1. 配置依赖文件

在主项目(或需要使用 SDK 的项目)下,在其对应的podfile的文件中,配置以下的依赖库。 其中第三方依赖库可以根据需要调整版本号。

bash
//xlink依赖库
#远程库
pod 'XFServerManagerFramework'
pod 'XFH5ServerFramework'
  1. 添加本地库文件(非必须步骤)

如果使用家居模块的话,还需要进行以下本地库的引用

将提供的LocalPods文件夹下所有内容复制到工程所在目录根目录中; 并配置路径:

$xlink_local_path = "./LocalPods"
bash
#本地库
pod "XLinkHomeKit", :path => "#$xlink_local_path/XLinkHomeKit/XLinkHomeKit.podspec"

2.2、应用权限要求

SDK 使用时需要使用到以下的权限。部分权限是业务场景中具体使用到的,不使用到相应的业务功能可以移除掉相关的权限。

<key>NSCameraUsageDescription</key>
<string>使用您的相机或相册完成应用内图片的拍摄和选择,以及二维码扫描功能。</string>
<key>NSMicrophoneUsageDescription</key>
<string>使用您的麦克风应用可视对讲、语音控制等功能</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>使用您的相机或相册完成应用内图片的拍摄和选择</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>使用您的相机或相册完成应用内图片的拍摄和选择</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>使用您的位置来获取附近的房屋或项目信息,允许系统使用定位,才能使用APP配网功能</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>使用您的位置来获取附近的房屋或项目信息,允许系统使用定位,才能使用APP配网功能</string>
<key>NSLocationUsageDescription</key>
<string>使用您的位置来获取附近的房屋或项目信息,允许系统使用定位,才能使用APP配网功能</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>使用您的位置来获取附近的房屋或项目信息,允许系统使用定位,才能使用APP配网功能</string>
  1. 部分敏感权限说明
权限使用范围
蓝牙用于APP配网
定位用于APP配网以及获取业主附近的房屋
相机扫描二维码加入家庭

3、SDK 初始化

SDK 集成后需要在使用前初始化。必须确保 SDK 初始化后才能正常使用。初始化 SDK 的部分配置以配置文件的方式提供,需要加载配置文件进行初始化。

建议在application:didFinishLaunchingWithOptions:方法里进行初始化

注意不能修改配件文件名称。

  1. 配置并初始化 SDK
objective-c
//默认的配置初始化,必须使用这个初始化
[XFUnionKit autoInit];

通过以上的操作,初始化操作就完成了。请留意日志中是否有相关的错误信息输出,有的话请参考错误信息说明处理或进行反馈。

4、SDK 使用

SDK 的核心为服务,通过提供各种服务来解决业务需求或功能的使用。

tips:服务的介绍说明请参考APP集成说明

三、服务调用

SDK 初始化成功后,即可调用相关的服务,服务调用时统一从 XFServerManager 中获取服务并使用。

1、显式调用

服务支持显式调用,显式调用时表示调用者明确知道自己使用的服务类型,并且必须依赖具体的服务类型。一般的显式调用如下:

objective-c

// 明确知道服务是 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;
    }
}];

其中 getServer 的操作会确保服务在使用前初始化,该操作是异步的。

2、隐式调用

服务也支持隐式调用,隐式调用时,调用者可以不明确知道自己使用的服务类型,或服务操作,但是必须明确服务调用需要的参数及返回信息。一般的隐式调用如下:

objective-c

[XFServerManager createInvokeBuilder:^(XFServerInovkeBuilder * _Nonnull builder) {
    //指定调用的服务ID
    builder.serverId = @"A";
    //指定调用的服务路由
    builder.routerPath = @"B";
    //配置服务使用的参数,这里参数的类型和数值需要和服务提供者确认。
    builder.param = @"context"
} invokeServerWithCallback:^(NSDictionary * _Nullable result, NSError * _Nullable error) {
    //调用服务返回的数据。
}];
  1. 隐式调用的前提是调用者与被调用者是通过约定的方法进行调用的,如果双方没有约定好或者是不清楚时,可能导致入参错误或出参类型错误,则无法正确完成调用。 在以上示例中,表示:通过调用服务ID为“A”的服务,并使用路由地址为“B”的功能,提供服务需要的参数“context”,调用服务得到返回类型为“NSDictionary”类型的数据。
  2. 隐式调用是需要服务本身支持的,如果服务没有实现路由功能的支持与处理,进行隐式调用是肯定会失败的
  3. 隐式调用时,返回的参数类型默认是支持可空类型的,在实现时需要留意一下。

授权服务

一、简介

用户授权服务是在C端 APP 中提供用户登录后的授权信息管理的服务。包含对授权信息的缓存与更新,并提供基础的用户授权操作。由于用户的实际授权方式有多种(包含账号密码登录、手机短信验证码登录、第三方账号登录等),授权服务仅提供最常用的账号密码登录功能。其它的功能请通过C端 APP 的 API 完成登录操作。

授权服务的主要功能包含:授权信息的缓存与管理

二、服务功能

1、用户授权登录

通过授权服务进行登录时,服务默认会将授权登录成功后的授权信息缓存到服务中,后续需要授权信息时直接使用即可。

objective-c
XFAuthServer *authServer = (XFAuthServer *)[[XFServerManager shareInstance] getServer:[XFAuthServer getId]];
NSString *account = @"账号";
NSString *password = @"密码";

[authServer authWithAccount:account password:password resource:nil callback:^(NSDictionary * _Nullable result, NSError * _Nullable error) {
    if (error) {
        //登录失败
    } else {
        //登录成功后的 xlink 用户授权信息
        // SDictionary *userInfo = result;
    }
}];

2、第三方用户授权服务

当不通过授权服务进行登录,或者是授权服务无法满足需要的登录方式,通过外部的登录方式获取到授权信息后,可以通过以下的方式将授权信息缓存到授权服务中,以便在其它地方或供其它的服务使用。

objective-c
XFAuthServer *authServer = (XFAuthServer *)[[XFServerManager shareInstance] getServer:[XFAuthServer getId]];
NSString *openId = @"APP在第三方平台登录成功返回的用户标识";
NSString *accessToken = @"APP在第三方平台登录成功返回的用户凭证";
NSString *nickName = @"第三方用户昵称";
NSString *resource = @"登录源,用户可以在登录时指定登录源,不同登录源可同时登录,长度在0~16个字符之间";

[authServer authThirdPartWithOpenId:openId accessToken:accessToken nickName:nickName resource:resource callback:^(NSDictionary * _Nullable result, NSError * _Nullable error) {
    if (error) {
        //登录失败
    } else {
        //登录成功后的 xlink 用户授权信息
        // SDictionary *userInfo = result;
    }
}];

3、缓存授权信息

当不通过授权服务进行登录,或者是授权服务无法满足需要的登录方式,通过外部的登录方式获取到授权信息后,可以通过以下的方式将授权信息缓存到授权服务中,以便在其它地方或供其它的服务使用。

objective-c

XFAuthServer *authServer = (XFAuthServer *)[[XFServerManager shareInstance] getServer:[XFAuthServer getId]];

// 创建AuthInfo对象并赋值,这里掠取赋值过程,需要根据实际请求得到的数据进行authInfo对象的各个属性(userId/accessToken/refreshToken/authorize)赋值。
XFLoginInfo *authInfo = [[XFLoginInfo alloc] init];

[authServer saveUserAuthInfo:authInfo];

4、监听授权信息变更

如果需要对授权信息变更进行监听,授权服务也提供了相应的功能以便其它服务使用。

objective-c
XFAuthServer *authServer = (XFAuthServer *)[[XFServerManager shareInstance] getServer:[XFAuthServer getId]];
[authServer addAuthChangedCallback:^(NSDictionary * _Nullable result) {
    // result为 用户授权信息更新成功后的 xlink 用户信息
        
}];

APP原生应用开发

一、原生应用开发

如果需要开发原生应用并集成到C端 APP 中使用时,可以通过自定义服务实现该功能。C端 APP 基于 XMAF 服务框架使用,所以将自定义的服务注册到 XMAF 框架后,在C端 APP 中可以通过服务间的通讯与操作完成功能的调用。

下面通过一个简单的示例来表示自定义服务如何实现及使用。详细的说明请参考下文。大概流程是:

  1. 服务开发者创建自定义服务
  2. 应用开发者集成并注册服务
  3. 应用开发者调用相应的服务

注意自定义服务的创建人员是服务提供者,集成到应用中并使用该服务功能的人员是服务调用者,两者的身份是不同的,可以是同一开发人员,也可以是不同的开发人员。

1、创建自定义服务

自定义服务是由服务提供者创建的。

1.1、实现 XIServer 接口

所有的服务都需要实现 XFIServer 的接口。服务有自己的生命周期,由服务管理模块进行调度与处理。 实现上可以声明为XFIServer的Protocol。

objective-c
@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、定义服务功能

每个服务都可以有自己单独的功能,功能以普通的实例方法提供。

objective-c
@interface XFCustomServer : NSObject <XFIServer>
//...省略上述创建的内容
//创建的实例方法,用于显性调用
- (void)customFunction;

@end

tips:某些场景可能需要使用到C端 APP 中的基础信息,如用户授权信息,用户数据等,请参考C端 APP 提供的基础服务。

1.3、确认服务提供的调用方式

APP SDK的使用中,提及了服务的调用方式有两种,显式调用与隐式调用。在定义了服务的功能方法之后,服务就可以满足显式调用的方式使用了。

但是如果需要服务支持隐式调用,则需要实现服务的路由功能,否则无法完成服务的隐式调用。实现服务的路由功能时,需要实现服务接口中路由相关的方法。

1.3.1、定义路由功能

定义当前服务需要提供的功能以隐式方式提供时,使用的路由信息。调用者将通过该路由信息对相应的功能准确地调用。

objective-c
//定义路由的功能,此处为登录页面的跳转
NSString * const XFCustomServerCustomFunctionPath = @"/XFCustomServer/customFunction";
1.3.2、实现路由功能的支持与处理

确定了路由信息后,需要实现与路由相关的方法,用于实现路由的功能处理。本质上相当于通过约定类似于 API 的访问方式,以指定的路由信息访问相关的功能或资源,并且返回操作的结果。

请注意所有的服务隐式调用时,返回的结果都是异步操作对象 XFAsyncAction

objective-c
@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、初始化时自动注册服务
objective-c
//初始化时注册自定义服务
[XFUnionKit autoInit];

如果需要在初始化时自定义服务,需要在xlink_config.xf文件中加入以该服务的serverId为key,如果需要在初始化时传入一些参数,可以将参数放置在value。示例如下:

json
"XFCustomServer":{
    "custom_key1":"custom_value1",
    "custom_key2":"custom_value2"
}
2.2、手动注册服务

如果没有定义在xlink_config.xf文件中,则需要手动进行服务注册。 在任何时候,如果服务未注册时,都可以在使用前再进行注册并使用。

objective-c
//注册并初始化返回该服务
[[XFServerManager shareInstance] registerServer:[XFCustomServer new]];

3、服务调用

服务的调用与开发指南中的服务调用一致。主要有两种方式,其中隐式的调用方式由服务提供方决定是否支持。在需要进行模块依赖的解耦与功能模块化时,推荐实现并使用隐式服务,调用者不需要关心具体的服务由谁提供,仅需要提前约定好使用的服务ID,路由信息及参数即可,在约定的规范不变的情况下,服务的提供方可以进行任何的更换。

3.1、显式调用
objective-c
// 明确知道服务是 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、隐式调用
objective-c
[XFServerManager createInvokeBuilder:^(XFServerInovkeBuilder * _Nonnull builder) {
    //指定调用的服务ID
    builder.serverId = @"A";
    //指定调用的服务路由
    builder.routerPath = @"B";
    //配置服务使用的参数,这里参数的类型和数值需要和服务提供者确认。
    builder.param = @"context"
} invokeServerWithCallback:^(NSDictionary * _Nullable result, NSError * _Nullable error) {
    //调用服务返回的数据。
}];