# 闲闲SDK-国内版-iOS接入文档
<center>当前版本v3.2.0</center>

[toc]

> 🌍 闲闲SDK-国内版Server接入文档：[https://psm4i21lig.feishu.cn/docx/AdbQdXR6fomDU8xJFX0cdsn7ndc](https://psm4i21lig.feishu.cn/docx/AdbQdXR6fomDU8xJFX0cdsn7ndc)

## 更新日志

- v3.2.0：2025.5.15
  - 修复已知bug，完善功能

=== [基础篇] ===

## 环境支持

- iOS: `13.0` 及以上
- 架构: `arm64`
- Xcode:  `15.2` 及以上
  - 上传AppStoreConnect 所需 Xcode版本参考Apple官方文档 [https://developer.apple.com/ios/submit/](https://developer.apple.com/ios/submit/) `实时更新`

## 集成SDK

### 参数准备

集成所需参数如下：

- SDK App ID（必要）
  - appid  // 配置 `URL Scheme` 处使用

### 接入方式

>  SDK目前只支持静态库接入方式

将所有文件添加到Xcode工程中，确保在工程的主目录下

### 添加依赖库（必要）

**配置规则：**

> 在Xcode工程中，选择你的工程设置项-->选中"TARGETS"一栏对应的Target-->在"Build Phases"标签栏的-->"Link Binary With Libraries"添加

- **libc++.1.tbd**

### Other Linker Flags（必要）

**配置规则：**

> 在Xcode工程中，选择你的工程设置项-->选中"TARGETS"一栏对应的Target-->在"Build Phases"标签栏的-->"Build Settings"搜索 Other Linker Flags 并添加
>
> ![linker](https://cdn.jsdelivr.net/gh/zhmbo/static@master/img/202504091756997.png)

- **-ObjC**

### 设置Info.plist

**配置规则：**

> 在Xcode工程中，选择你的工程设置项-->选中"TARGETS"一栏对应的Target-->在"info"标签栏的

#### URL Schemes 

**配置规则：**

> 在Xcode工程中，选择你的工程设置项-->选中"TARGETS"一栏对应的Target-->在"info"标签栏的-->"URL Types"

##### URL Schemes = "app"+"appid" （必要）

> 例如：appid 为：352e8711bcca025e07230a8402f03d09
>
> 则配置对应的 URL schemes：app352e8711bcca025e07230a8402f03d09
>
> ![app352e8711bcca025e07230a8402f03d09](https://cdn.jsdelivr.net/gh/zhmbo/static@master/img/202504081827815.png)

```xml
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>app352e8711bcca025e07230a8402f03d09</string>
    </array>
  </dict>
</array>
```

#### 权限（必要）

**配置规则：**

> 在Xcode工程中，选择你的工程设置项-->选中"TARGETS"一栏对应的Target-->在"info"标签栏的-->"URL Types"-->""Custom iOS Target Properties"

##### 配置获取IDFA权限

> **NSUserTrackingUsageDescription**
>
> ![idfa](https://cdn.jsdelivr.net/gh/zhmbo/static@master/img/202504081919728.png)

```xml
<key>NSUserTrackingUsageDescription</key>
<string>App需要访问您的设备标识符(IDFA)，用于提供更契合您兴趣的内容，减少无关广告推荐</string>
```

##### 配置获取Photo权限

> **NSPhotoLibraryAddUsageDescription**
>
> ![photo](https://cdn.jsdelivr.net/gh/zhmbo/static@master/img/202504081924488.png)

```xml
<key>NSPhotoLibraryAddUsageDescription</key>
<string>APP需要您的同意，才能访问相册进行保存账号密码截图到您的相册，如禁止将无法完成保存操作</string>
```

### PrivacyInfo.xcprivacy

根据2024年5月1日Apple新隐私条款：

[https://developer.apple.com/documentation/bundleresources/privacy-manifest-files?language=objc](https://developer.apple.com/documentation/bundleresources/privacy-manifest-files?language=objc)

[https://developer.apple.com/support/third-party-SDK-requirements/](https://developer.apple.com/support/third-party-SDK-requirements/)

做哪些：

- 工程中添加 PrivacyInfo.xcprivacy
- 第三方库中添加 PrivacyInfo.xcprivacy

参考获取文件方式：

- https://github.com/kimbely0320/update_privacy_info.py

- https://www.privacymanifest.dev/

## SDK使用方式

### 启动（必要）

如使用AppDelegate：

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 如果您的应用程序使用UIScene ，请从UISceneDelegate实现以下方法，这里无需实现
    [XXGPlayCN xxpk_didFinishLaunchingWithOptions:launchOptions xconnectOptions:nil];
    
    return YES;
}
```

如使用SceneDelegate：

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // 如果应用程序使用的 UIScene，下面方法无需在AppDelegate里实现，只在这里实现
    [XXGPlayCN xxpk_didFinishLaunchingWithOptions:nil xconnectOptions:connectionOptions];
}
```

***<font color=red>注意：</font>*** **！！需要注意的是，以上两种方式，根据接入工程时机情况，选择对应方案即可，且需要注意，两种方案透传给SDK的数据结构不同，AppDelegate方案需要传launchOptions，SceneDelegate方案需要传connectionOptions。**

### App通用链接回调（必要）

如使用AppDelegate：

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    // 如果您的应用程序使用UIScene ，请从UISceneDelegate实现以下方法，这里无需实现
    [XXGPlayCN xxpk_applicationOpenURL:url xoptions:options xURLContexts:nil];
    return YES;
}
```

如使用SceneDelegate：

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
  
    // 如果应用程序使用的 UIScene，下面方法无需在AppDelegate里实现，只在这里实现
    [XXGPlayCN xxpk_applicationOpenURL:URLContexts.allObjects.firstObject.URL xoptions:nil xURLContexts:URLContexts];
}
```

### 设置SDK代理（必要）

> **设置代理用于接收登录、退出、支付、上报角色结果**

```objective-c
// 1.引入
#import <XXGPlayKitCN/XXGPlayKitCN.h>
// 2.遵循协议
@interface ViewController ()<XXGPlayDelegate>
// 3.设置代理
[XXGPlayCN xxpk_setPlayDelegate:self];

// 4.实现代理方法
// MARK: XXGPlayDelegate
///登录回调（必接）
- (void)xxpk_comeinFinish:(NSDictionary *)box {
    NSLog(@"登录成功 - %@", box);
}

//退出回调（必接）
// 必接 - 对接方需在此回调中调用游戏切换账号接口,退到游戏【登录界面】
// SDK个人中心有切换账号功能，所以用户在个人中心操作切换账号需游戏一并退出
// 另外游戏内退出同时调用SDK的logout:函数也会走此回调，
// 所以建议游戏的退出接口直接调用SDK的logout:在此回调中一并退出，不然游戏会重复退出2次
- (void)xxpk_logouted {
    NSLog(@"退出成功");
    // 必接 - CP 需在此回调中调用游戏切换账号接口,退到游戏【登录界面】
}

//支付回调
- (void)xxpk_payFinished:(BOOL)isSuc {
    NSLog(@"支付%@", isSuc?@"成功":@"失败");
}

//上报角色回调
- (void)xxpk_uploadRoleFinished:(BOOL)isSuc {
    NSLog(@"上报角色%@", isSuc?@"成功":@"失败");
}
```

### 登录（必要）

- 在游戏登录界面加载完成后调用及自动登录.(也可通过登录按钮让用户点击完成登录操作)
- 登录完成后会通过代理方法**"xxpk_comeinFinish: "**返回用户信息，类型为NSDictionary

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

/**
 * 在游戏登录界面加载完成后调用及自动登录.(也可通过登录按钮让用户点击完成登录操作)
 * 登录完成后会通过代理方法：xxpk_comeinFinish: 返回用户信息
 */
// 登录接口
[XXGPlayCN xxpk_comein];
```
- xxpk_comeinFinish:回调返回参数示例：

```json
{
    "id" : "62072919",
    "name" : "G25040962072919",
    "time" : "1744192861",
    "token" : "7fdf2ff6b4ba44f0284b2adada2652bb",
    "type" : 0
}
```

### 退出登录

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

// 退出接口
[XXGPlayCN xxpk_logout];
```

- xxpk_logouted 方法回调退出

### 支付（必要）
> 订单模型,具体查看属性注释和文档说明  
> 这里注意：确保传进的参数都为**NSString**类型，不接受NSNumber和其他类型
> 支付结果通过代理方法**"xxpk_pFinished:"**返回 YES为成功，NO为失败

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

NSString *cpOrderId = NSUUID.UUID.UUIDString;       // 游戏生成的订单号 (必传)
NSString *productCode = @"com.xxgame.sdk.demo.228"; // 商品标识(苹果商品标识)(必传)
NSString *amount = @"228";                          // 商品金额（单位：元） (必传)
NSString *productName = @"SDK测试商品";               // 商品名称、例：60元宝 (必传)
NSString *serverId = @"20190927001";                // 用户游戏角色所在的服务器id (必传)
NSString *roleId = @"100001";                       // 用户游戏角色ID (必传)
NSString *roleName = @"角色-XXGameSDK";              // 用户游戏角色名称 (必传)
NSString *roleLevel = @"99";                         // 用户游戏角色等级 (必传)
NSString *extraInfo = @"2019";                       // 订单额外信息，最终将回传给游戏服务器 (选传)

/**
 * 支付,传入订单模型
 * 支付结果通过代理方法xxpk_payFinished:返回 YES为成功，NO为失败
 */
[XXGPlayCN xxpk_createOrder:cpOrderId
         xxpk_productCode:productCode
              xxpk_amount:amount
         xxpk_productName:productName
            xxpk_serverId:serverId
           xxpk_extraInfo:extraInfo
              xxpk_roleId:roleId
            xxpk_roleName:roleName
           xxpk_roleLevel:roleLevel];
```

### 上报角色信息（必要）

如服务端已对接此接口客户端无需对接

> 调用时机(重要!!只在以下三个场景需调用):  
>  1、玩家在选择区服进入游戏时调用该接口
>  2、创建角色时调用该接口
>  3、角色升级或其他角色汇报信息发生变化时调用该接 


```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

/**
 * 必要！！！（有 3 处需要调用此接口）
 * 必要！！！（有 3 处需要调用此接口）
 * 必要！！！（有 3 处需要调用此接口） 
 * 注意：确保传进的参数都为NSString类型，不接受NSNumber类型，extend字段类型为字典
 * 调用时机(重要!!只在以下三个场景需调用):
 * 1. 玩家在选择区服进入游戏时调用该接口。
 * 2. 创建角色时调用该接口
 * 3. 角色升级或其他角色汇报信息发生变化时调用该接
 */
// 角色所在服务器id (必传)
NSString *serverId = "9001";
// 用户游戏角色ID (必传)
NSString *roleId = "xx100921";
// 角色名称 (必传)
NSString *roleName = "阿斯蒂芬";
// 角色等级 (必传)
NSString *roleLevel = "109";
// 角色扩展信息（选填）类型：字典
NSDictionary *extend = @{
    @"pet": "5",          //宠物等级（5）
    @"horse": "1",        //坐骑等级（1）
    @"power": "10092",        //战力（100）
    @"promote": "2",      //转职（2转）
    @"married": "0",      //'0': 未婚, '1': 已婚
    @"liveness": "2000"),     //活跃度 (2000)
    @"hero_level": @"98",               //英雄等级(98级)
    @"trumps": @[ //已激活的法宝列表
         @"fabao1",   //法宝1
         @"fabao2"    //法宝2
    ],
    @"wings": @[  //已激活的翅膀列表
         @"wing1",    //翅膀1
         @"wing2"     //翅膀2
    ],
    @"artifacts": @[  //已激活的神器列表
         @"artifact1",    //神器1
         @"artifact2",    //神器2
    ],
    //@"xxx":@"xxx"                     //其他自定义信息
    //@"xxx":@"xxx"                     //其他自定义信息
    //@"xxx":@"xxx"                     //其他自定义信息
    //...
};

/**
 上报角色信息
 */
[XXGPlayCN xxpk_uploadRoleInfo:serverId
								 xxpk_roleId:roleId
               xxpk_roleName:roleName
              xxpk_roleLevel:roleLevel
                 xxpk_extend:extend];
```

### 其他配置

#### 登录界面关闭接口（可选接口）

> 隐藏SDK界面右上角关闭按钮默认为：YES 隐藏状态
>
> 如果游戏登录界面没有登录按钮用来拉起SDK登录界面，不用调用或设置为YES，以免用户关闭后无法重新拉起登录界面

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

[XXGSetting xxpk_setCloseButtonHidden:YES];
```

=== [巨量篇] ===

## 巨量SDK 集成

### URL Schemes 配置

#### URL Schemes = 包名

> 例如：假设一个包的包名为：com.test.example;
>
> 则配置对应的 URL schemes： com.test.example；
>
> ![com.test.example](https://cdn.jsdelivr.net/gh/zhmbo/static@master/img/202504081906539.png)

```xml
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>com.test.example</string>
    </array>
  </dict>
</array>
```

=== [Sigmob篇] ===

## Sigmob SDK 集成

### Sigmob功能接口

#### Sigmob激励广告

```objective-c
#import <XXGPlayKitCN/XXGPlayKitCN.h>

[XXGPlayCN xxpk_sigmobShowAdComplate:^(BOOL result) {
    [self demo_log:[NSString stringWithFormat:@"广告获得激励-%@", result?@"成功":@"失败"]];
}];
```

