iOS 集成方法
1 前言
在您阅读此文档时,我们假定您已经具备了基础的 iOS 应用开发经验,并能够理解相关基础概念。
1.1 环境准备
请到拓课官方网站下载 Talkcloud SDK iOS 版。 如果您打算使用拓课公网服务器,使用 DEMO 里填写的默认参数即可进入教室;
1.2 版本兼容
兼容 iOS 12 及以上版本。
2 工程设置
2.1 Xcode Version 11+
2.2 导入 Framework:
添加库 TKRoomSDK.framework、TKWhiteBoard.framework、TKUISDK.framework 三个 framework。到 TARGETS -> Framework,Lbraries,and Embedded Content 下的 Embed 属性都设置为 Embed&Sign。
2.3 Info.plist 文件的设置
添加权限申请及相应文本
| Privacy - Camera Usage Description
Privacy - Microphone Usage Description
Privacy - Photo Library Additions Usage Description
Privacy - Photo Library Usage Description
Privacy - Location When In Use Usage Description
|
2.4 添加第三方库
1
2
3
4
5
6
7
8
9
10
11
12 | //闪退统计(非必须)
pod 'Bugly', '2.5.0'
//如果使用分享功能可添加以下三方库,具体根据需求确定(非必要)
pod 'UMCommon', '7.2.5'
pod 'UMShare/UI', '6.10.1'
# 微信完整版
pod 'UMShare/Social/WeChat', '6.10.1'
# 集成QQ/QZone/TIM(完整版7.6M)
pod 'UMShare/Social/QQ', '6.10.1'
# 集成新浪微博(完整版25.3M)
pod 'UMShare/Social/Sina', '6.10.1'
|
2.5 http 请求
| App Transport Security Settings Allow Arbitrary Loads YES
|
2.6 uild Settings 设置项
| Enable Bitcode : NO
User-Defined : arm64
OTHER_LDFLAGS : 加入 -ObjC
|
2.7 外部链接打开
app 的 url schemes
targets -> info -> URL Types
添加 协议头 enterroomnew(添加此协议头后 在浏览器点击特定链接才可以打开 app,此协议头可和后端协商自定义,enterroomnew 为拓客云默认协议头)
3 AppDelegate.m 文件的配置
3.1 引入头文件
| #import <TKUISDK/TKUISDK.h>
|
3.2 回调方法里加入对应的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 使用拓课云登录界面(非必须调用)
// [[TKAPPSetConfig shareInstance] setLoginViewForRootViewController:self.window];
// 加载自定义的loadingGIF图,key值为 企业的authkey。
// 不调用此方法,或者key值传空,加载默认的GIF图。
// [[TKAPPSetConfig shareInstance] roomLoadingImageWithPath:@""];
// 初始化 bugly 收集闪退日志
// (app没有闪退收集系统时建议调用该方法、以便于解决相关闪退问题)
// BuglyConfig *bc = [BuglyConfig new];
// bc.version = [[TKAPPSetConfig shareInstance] getUISDKVersion];
// [Bugly startWithAppId:@"9950489142" config:bc];(该buglyID为拓课云所有)
详见DEMO
}
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
//添加通过链接跳转APP的方法
[[TKEduClassManager shareInstance] joinRoomWithUrl:url.relativeString];
}
-(void)applicationWillTerminate:(UIApplication *)application {
// 在程序被kill的时候,添加退出房间的方法
[[TKEduClassManager shareInstance] leaveRoom];
}
-(void)applicationDidBecomeActive:(UIApplication *)application {
// 添加用于恢复数据的方法
[[TKEduClassManager shareInstance] applicationDidBecomeActive];
}
|
4 SDK 使用说明
TKUISDK.framework提供了所有的教室功能;
TKWhiteBoard.framework 提供了所有的白板功能;
TKRoomSDK.framework 提供音视频流的传输、信令的传递以及重要功能逻辑的实现。
将以上 framework 引入工程
5 TKUISDK.framework
5.1 TKAPPSetConfig 类主要提供了进入教室前的配置信息的接口。
5.2 TKEduRoomDelegate 类提供了进入教室的一些回调,可根据自己的需求使用。
5.3 TKEduClassManager 类提供了以下的方法:
a.进入房间的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | /**
进入房间的函数
@param paramDic NSDictionary类型,键值需要传递
serial(NSString * 课堂号)、
userrole(NSNumber * 学生 2,老师 0,旁听生 6, 巡课 4)、
nickname(NSString * 用户昵称)、
userid(NSString * 用户ID,选填)、
password(NSString * 密码 有则传)、
norecord(是否不录制当前用户视频 0,录制 1,不录制)
桌面共享:bundleid (桌面共享进程的bundleid,为空视为无共享功能) 、groupid (桌面共享的appGroupid)
@param controller 当前页面的控制器,通常与下边delegate相同
@param delegate 遵循TKEduEnterClassRoomDelegate代理,供给用户进行处理
@param isFromWeb 是否是从网址链接进入进入
@return 是否成功 0 成功 其他失败
*/
- (int)joinRoomWithParamDic:(NSDictionary*)paramDic
ViewController:(UIViewController*)controller
Delegate:(id<TKEduRoomDelegate>)delegate
isFromWeb:(BOOL)isFromWeb;
|
b.通过链接进入教室\直播\回放:
| /**
从网页链接进入房间(直播\回放)
@param url 网页url userid (&拼接userid 只播放老师和该userid学生)
*/
- (void)joinRoomWithUrl:(NSString*)url;
|
c.进入常规回放:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | /**
进入回放房间的函数
@param paramDic NSDictionary类型, 键值需要传递serial(NSString * 课堂号)、
recordtitle(NSString * 根据后台返回的回放标题)、
userid(NSString * 用户ID,选填 传入后只播放除老师外该id的音视频)
@param controller 当前页面的控制器,通常与下边delegate相同
@param delegate 遵循TKEduEnterClassRoomDelegate代理,供给用户进行处理
@param isFromWeb 是否是从网址链接进入进入
@return 是否成功 0 成功 其他失败
*/
- (int)joinPlaybackRoomWithParamDic:(NSDictionary *)paramDic
ViewController:(UIViewController*)controller
Delegate:(id<TKEduRoomDelegate>)delegate
isFromWeb:(BOOL)isFromWeb;
|
d.进入 mp4 回放(建议使用):
| /** 播放视频
@param vc 控制器用于弹出播放页面
@param path 视频路径
@param style 播放器主题 0:默认主题;1:暗色主题; 2:黑色主题
*/
-(void)playVideo:(UIViewController *)vc path:(NSString *)path style:(NSInteger)style;
|
| /** 进入MP4回放页面
@param path MP4回放地址
@param controller 代理
@param skipTime 时间点 (选填 可传" ")
@param breakurl breakurl (选填 可传" ")
*/
- (void)joinRoomWithPlaybackPath:(NSString*)path ViewController:(UIViewController*)controller skipTime:(NSString *)skipTime breakurl:(NSString *)breakurl;
|
f.展示设备检测页面):
| /// 展示设备检测页面
/// @param vc 控制器用于弹出设备检测页面
-(void)showDeviceStatusCheck:(UIViewController *)vc;
|
*TKWhiteBoard.framework 和 TKRoomSDK.framework 已在 TKUISDK.framework 中调用,除非有特定需求,否则无需额外调用。
6 插件-友盟分享(可选)
添加分享功能(友盟)
(1) pod 集成友盟插件
| pod 'UMCommon', '7.2.5'
pod 'UMShare/UI', '6.10.1'
# 微信完整版
pod 'UMShare/Social/WeChat', '6.10.1'
/// QQ 新浪 暂未开通
# 集成QQ/QZone/TIM(完整版7.6M)
pod 'UMShare/Social/QQ', '6.10.1'
# 集成新浪微博(完整版25.3M)
pod 'UMShare/Social/Sina', '6.10.1'
|
(2)添加文件
将 demo 中 TKUIDEMO -> PluginClass 文件夹添加到工程中
(3)添加代码(需要提前准备 友盟、微信等平台账号,并填写相关信息获取 相关参数)(相关问题可以自行百度)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 添加
[self addTKSharePlugin];
return YES;
}
- (void) addTKSharePlugin {
// 友盟分享(如果使用需要完成以下内容)
// 1 pod 集成相关UM库(参考podfile)
// 2 在 UM 和 微信 平台创建账号并申请权限(当前版本只支持分享到微信好友和朋友圈)并完成相关配置
// 3 填写 TKUMShareSettings 分享内相关宏定义的值. APP启动时调用 [TKUMShareSettings UMShareSettings] 初始化分享,
[TKUMShareSettings UMShareSettings];
// 进入教室前 设置分享回调
_sharePlugin = [[TK_SharePlugin alloc] init];
[[TKAPPSetConfig shareInstance] registerSharePlusin:_sharePlugin];
}
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
if ([url.relativeString containsString:@"enterroomnew://"]) {
[[TKEduClassManager shareInstance] joinRoomWithUrl:url.relativeString];
[TKEduClassManager shareInstance].isUrlOpen = YES;//记录外部链接打开
} else {
#if __has_include(<UMShare/UMShare.h>)
//6.3的新的API调用,是为了兼容国外平台(例如:新版facebookSDK,VK等)的调用[如果用6.2的api调用会没有回调],对国内平台没有影响
BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url options:options];
if (result == NO) {
}
return result;
#else
#endif
}
return YES;
}
#if __has_include(<UMShare/UMShare.h>)
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
if (![[UMSocialManager defaultManager] handleUniversalLink:userActivity options:nil]) {
// 其他SDK的回调
}
return YES;
}
#else
#endif
|
(4)工程配置 配置 Universal Link (有疑问可自行百度)
(5) 拓课云后台配置分享内容 (icon、url、text 等),配置好后创建的教室将携带相关信息,原有教室不携带。
7 屏幕旋转问题处理
一、原 app 仅支持竖屏模式
TARGETS -> General -> Deployment Info -> Device Orientation
勾选 Portrait、 Landscape Left、Landscape Right。
二、 原 app 支持旋转
1、AppDelegate.h 中添加
| + (AppDelegate *) appDelegate;
@property (nonatomic, assign) BOOL isTalkCloudTimes;
|
2、AppDelegate.m 中添加
1
2
3
4
5
6
7
8
9
10
11
12
13 | + (AppDelegate *) appDelegate {
return (AppDelegate *)[UIApplication sharedApplication].delegate;
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if (self.isTalkCloudTimes == YES) {
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
// demo 登陆页 支持左右横屏(此处根据自己工程实际需要做本地化修改)
return UIInterfaceOrientationMaskAll;
}
|
3、进入教室处 添加
(1)调用 joinRoomWithParamDic 方法前添加代码
| [AppDelegate appDelegate].isTalkCloudTimes = YES;
|
(2) TKEduRoomDelegate 代理中加入代码
| - (void)onEnterRoomFailed:(int)result Description:(NSString*)desc {
if (result == 0 && [desc isEqualToString:@"取消"]) {
[AppDelegate appDelegate].isTalkCloudTimes = NO;
}
}
- (void)leftRoomComplete {
[AppDelegate appDelegate].isTalkCloudTimes = NO;
}
|
4、添加后测试过程中,如果退出教室后页面方向错误:
(1)检测 appdelegate 中 自行根据本身项目配置的部分是否正确。
(2)晃动手机。看能使屏幕方向恢复正常。
5、需要晃一下手机才能恢复正常时:(这个和项目有关,不是必须的)
在 代码:
| [AppDelegate appDelegate].isTalkCloudTimes = NO;
|
后调用下面方法:
| - (void) setOrientations {
[[UIDevice currentDevice] setValue:[NSNumber numberWithInt:UIInterfaceOrientationUnknown] forKey:@"orientation"];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInt:UIInterfaceOrientationPortrait] forKey:@"orientation"];
}
|
注:第二行的方向为当前页面支持的某一方向
6、本方案 需要所有页面都做页面方向处理
| // New Autorotation support.
@property(nonatomic, readonly) BOOL shouldAutorotate API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(tvos);
@property(nonatomic, readonly) UIInterfaceOrientationMask supportedInterfaceOrientations API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(tvos);
// Returns interface orientation masks.
@property(nonatomic, readonly) UIInterfaceOrientation preferredInterfaceOrientationForPresentation API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(tvos);
|
8 配置桌面共享
8.1 主工程下新建 TARGETS
8.1.1 创建拓展工程
8.1.2 拓展工程配置
Build Settings -> Enable Bitcode -> NO
8.2 创建 App Groups
8.2.1 主工程与拓展工程勾选相同的 App Groups 完成两者之间通信
8.3 添加依赖库及代码
8.3.1 导入 TKScreenShareService.framework
复制 Demo 工程 SampleHandler 文件代码,并将 init 方法内 AppGroup 传参改为你所创建的 Group 名称(如图)
8.3.2 拓展工程添加依赖库
Deployment info iOS 支持版本需设置为 iOS12
8.3.3 主工程添加依赖库 TKScreenShareService.framework (如图)
9 常见问题描述
9.1 进入教室出现错误码
| (TKEduRoomDelegate -> - (void)onEnterRoomFailed:(int)result Description:(NSString*)desc;)
|
错误码 |
说明 |
3001 |
服务器过期 |
3002 |
公司被冻结 |
3003 |
课堂被删除或过期 |
4007 |
课堂不存在 |
4008 |
课堂密码错误 |
4103 |
课堂人数超限 |
4110 |
该课堂需要密码,请输入密码 |
(在此只列举部分错误码,更详细错误码请参考 TKRoomSDK.framwork 中的 TKRoomDefines 类。)
9.2 获取录制件接口(回放 path 参数获取方式): getrecordlist
请求 URL: https://global.talk-cloud.net/WebAPI/getrecordlist
请求方式:POST
参数:
参数 |
必选 |
类型 |
说明 |
key |
是 |
String |
企业 key |
serial |
是 |
String |
房间号 |
thirdroomid |
是 |
String |
第三方教室号:和 serial 二选一必填 |
starttime |
否 |
int |
开始时间(时间截:1597852800) |
endtime |
否 |
int |
结束时间(时间截:1597852800) |
recordtype |
否 |
int |
返回录制件类型(0 常规,1mp4,2 所有),默认只返回常规 |
返回示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 | {
"result": 0,
"recordlist": [
{
"recordid": "1000610044773851543565780miarfiuv",
"serial": "10044277385",
"companyid": "100026",
"recordtitle": "1543565779986",
"starttime": "1543565780",
"duration_ms": 1394883,
"size": "432722377",
"webhost": "https://local.global.com",
"recordpath": "/0904754e-f255-4070-8075-c99f517adbb8-1004477385/",
"state": "0",
"playpath": "http://local.global.com/replay/1004477385/10006/1543565779986/",
"https_playpath": "https://local.global.com/replay/1004477385/10006/1543565779986/"
},
{
"recordid": "10108013994234561603071801rtvsdgju",
"serial": "10044277385",
"companyid": "100026",
"recordtitle": "1603071800847",
"starttime": "1603071801",
"duration_ms": 2234,
"size": "1368886",
"webhost": "https://local.global.com",
"recordpath": "/700ef742-f37a-4932-a85c-be5e4dcf09bf-1399423456/",
"state": "0",
"playpath": "",
"https_playpath": "",
"playpath_mp4": "http://record.talk-cloud.net/700ef742-f37a-4932-a85c-be5e4dcf09bf-1399423456/record.mp4",
"https_playpath_mp4": "https://record.talk-cloud.net/700ef742-f37a-4932-a85c-be5e4dcf09bf-1399423456/record.mp4",
"playpath_m4a": "",
"https_playpath_m4a": "",
"videoplayback_m4a": "",
"videoplayback_mp4": "https://global.talk-cloud.net/media/1399423456/101080/1603071800847/1/"
}
]
}
|
返回参数说明
参数 |
类型 |
说明 |
recordlist.recordid |
String |
录制件 ID |
recordlist.serial |
String |
房间号 |
recordlist.companyid |
String |
企业 ID |
recordlist.recordtitle |
String |
录制标题 |
recordlist.starttime |
String |
开始时间 |
recordlist.duration_ms |
Int |
时长(毫秒) |
recordlist.size |
String |
录制件大小 |
recordlist.webhost |
String |
访问域名 |
recordlist.recordpath |
String |
录制件路径 |
recordlist.state |
String |
录制件状态 |
recordlist.playpath |
String |
常规播放地址 |
recordlist.https_playpath |
String |
https 常规播放地址 |
recordlist.playpath_mp4 String |
String |
MP4 播放地址 |
recordlist.https_playpath_mp4 |
String |
httpsMP4 播放地址 |
recordlist.playpath_m4a String |
String |
M4A 播放地址 |
recordlist.https_playpath_m4a |
String |
httpsM4A 播放地址 |
recordlist.videoplayback_mp4 |
String |
视频播放地址 |
recordlist.videoplayback_m4a |
String |
音频播放地址 |
常规录制件 path 参数拼接方法
获取录制件,生成录制件(recordtype=0 convert = 1) 的时候。调用 getrecordlist 接口去获取 recordpath
播放回放的参数 path global.talk-cloud.net:8081 + recordpath
例: global.talk-cloud.net:8081/bb3ae4f7-1242-4752-a7bb-afe8f3f1ab87-1695310935/
9.3 通过 Cocoapods 导入的第三方库:参考 Podfile 文件.
如果使用到友盟,
SDK 版本需要一致(当前:UMCommon 7.2.5 UMShare 6.10.1)否则会版本冲突导致闪退
SDK 名称需要一致(UMCommon / UMCCommon)
| pod 'UMCommon', '7.2.5'
pod 'UMShare/UI', '6.10.1'
# 微信完整版
pod 'UMShare/Social/WeChat', '6.10.1'
# 集成QQ/QZone/TIM(完整版7.6M)
pod 'UMShare/Social/QQ', '6.10.1'
# 集成新浪微博(完整版25.3M)
pod 'UMShare/Social/Sina', '6.10.1'
|
9.4 本地语言简体中文 地区中国大陆 进入教室显示英文问题 添加本地支持支持语言
| targets -> Info -> Custom iOS Target Properties
添加 Localizations(类型:Array)
内容: Chinese(traditional)、Chinese(simplified)、English 三项
|