IOSPlatformSDK.mm 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. //
  2. // IOSPlatformSDK.m
  3. // OYGameSKD
  4. //
  5. // Created by leon on 2021/1/21.
  6. // Copyright © 2021 Oujia. All rights reserved.
  7. #import "IOSPlatformSDK.h"
  8. #import "BugTool.h"
  9. #pragma mark ============================>> ios call unity (定义名字参数和C#类一样的方法)
  10. //大概流程就是先将C#的函数指针存入OC内存,在OC需要回调unity的时候就可以使用不同的指针来回调不同的unity方法
  11. /**
  12. *运动数据
  13. * left: 左鞋动作代码
  14. * right: 右鞋动作代码
  15. * 对应 enum CMD_MOTION
  16. */
  17. typedef void (* MotionHandler) (int cusid, int left, int right);
  18. /**
  19. * 踏步状态,频率
  20. * leftStatus: 左鞋(0:停止, 1:慢,2:快)
  21. * rightStatus: 右鞋(0:停止, 1:慢,2:快)
  22. * leftFrag: 左鞋(每分钟步频)
  23. * rightFrag: 右鞋(每分钟步频)
  24. */
  25. typedef void (* StepHandler)(int cusid, int leftStatus, int rightStatus, int leftFrag, int rightFrag);
  26. /**
  27. * 返回蓝牙设备的基本信息,用于界面上显示当前的设备状况,app 跳转的时候传过来的
  28. * name: 设备名称
  29. * status: 设备状态 @see enum BLE_STATE
  30. * electricity: 设备电量 取值范围[0 - 100] 对比左右鞋 handler较低的电量
  31. */
  32. typedef void (* DeviceHandler)(int cusid, const char *name, const char *address, int status, int electricity);
  33. /**
  34. * 好友列表 unity call ios 异步请求数据后 ios call unity
  35. * 调用api GetUserFriends() 的回调
  36. * code: 请求结果代码 0: 成功, 非0: 根据业务处理
  37. * json: 好友列表数据 , json 数组
  38. *
  39. */
  40. typedef void (* UserFriendsHandler)(int code, const char * json);
  41. /**
  42. * 调用api GetUserFriends() 的回调
  43. * code: 请求结果代码 0: 成功, 非0: 根据业务处理
  44. * json: 好友列表数据 , json 数组
  45. */
  46. typedef void (* InviteFriendHandler)(int code, const char * userJson, const char * inviteInfo);//
  47. /**
  48. *游戏首页交互动作的回调
  49. * cusid: 主副设备
  50. * code: 交互代码
  51. */
  52. typedef void (* ActionHandler) (int cusid, int code);
  53. /**
  54. * 游戏榜单数据回调
  55. * cusid: 主副设备
  56. * code: 交互代码
  57. */
  58. typedef void (* GetRankHandler)(int conde,const char * userJson);
  59. /** array: x,y,z姿态数据
  60. * 单位:弧度
  61. * 使用时要将数据 除以 10000
  62. * 转换角度可以使用 Mathf.Rad2Deg
  63. */
  64. typedef void (* RotateHandler)(int cusid,int right_pos[3],int left_pos[3],int right_att[3],int left_att[3],int righrAcc[3],int leftAcc[3]);
  65. #pragma mark ============================>> 声明 静态指针变量的实例 在unity call ios时候将该指针存储在内存中,在需要ios call unity时,用该指针调用unity的函数接口
  66. static ActionHandler actionHandler;
  67. static MotionHandler motionHandler;
  68. static StepHandler stepHandler;
  69. static DeviceHandler deviceHandler;
  70. static UserFriendsHandler userFriendsHandler;
  71. static InviteFriendHandler inviteFriendHandler;
  72. static GetRankHandler getRankHandler;
  73. static RotateHandler rotateHandler;
  74. @implementation IOSPlatformSDK
  75. #pragma mark ============================>> SDK 单例
  76. static IOSPlatformSDK * instance;
  77. +(instancetype)sharedInstance{
  78. return [[self alloc] init];
  79. }
  80. + (instancetype)allocWithZone:(struct _NSZone *)zone{
  81. static dispatch_once_t onceToken;
  82. dispatch_once(&onceToken, ^{
  83. instance = [super allocWithZone:zone];
  84. });
  85. return instance;
  86. }
  87. - (instancetype)init{
  88. static dispatch_once_t onceToken;
  89. dispatch_once(&onceToken, ^{
  90. instance = [super init];
  91. //开启蓝牙
  92. [BTDataProcess sharedInstance];
  93. //bug监控
  94. [BugTool startAvoidBug];
  95. });
  96. return instance;
  97. }
  98. #pragma mark ============================>> public method app 跳转直链
  99. -(void)startWithUrl:(NSURL*)url{
  100. [BTDataInstance startWithUrl:url];
  101. }
  102. //
  103. #pragma mark ============================>> private
  104. //是否已经缓存到用户信息
  105. -(BOOL)existUserInfo{
  106. NSDictionary * jsonDict = [IOS_NSUSERDEFAULT objectForKey:IOSSDK_USERINFO];
  107. if ([jsonDict isKindOfClass:[NSNull class]] || jsonDict == nil || [jsonDict isEqual:[NSNull null]]){
  108. [PopupView showCusHUDA:@"获取用户信息失败,请从趣动启动"];
  109. return NO;
  110. }else{
  111. return YES;
  112. }
  113. }
  114. //
  115. #pragma mark ============================>> ios call unity (数据处理后的回调)
  116. -(void)bridgingMotionAction:(int)cusid
  117. left:(int)left
  118. right:(int)right{
  119. if (motionHandler!=nil){
  120. motionHandler(cusid,left,right);
  121. }
  122. }
  123. -(void)bridgingStepAction:(int)cusid
  124. leftStatus:(int)leftStatus
  125. rightStatus:(int)rightStatus
  126. leftFrag:(int)leftFrag
  127. rightFrag:(int)rightFrag{
  128. if (stepHandler != nil){
  129. stepHandler(cusid,leftStatus,rightStatus,leftFrag,rightFrag);
  130. }
  131. }
  132. -(void)bridgingDeviceAction:(int)cusid
  133. name:(NSString*)name
  134. address:(NSString*)address
  135. status:(int)status
  136. electricity:(int)electricity{
  137. // NSLog(@"deviceHandler ===>> %d %@ %@ %d %d",cusid,name,address,status,electricity);
  138. const char * charName =[name UTF8String];
  139. const char * charAddress =[address UTF8String];
  140. if (deviceHandler != nil){
  141. deviceHandler(cusid,charName,charAddress,status,electricity);
  142. }
  143. }
  144. -(void)bridgingInteraction:(int)cusid
  145. code:(int)code{
  146. //传给unity ---> 旧版游戏未用到
  147. if (actionHandler != nil){
  148. // actionHandler(cusid,code);
  149. }
  150. }
  151. -(void)bridgingInvite:(int)code
  152. userChar:(const char *)userChar
  153. infoChar:(const char *)infoChar{
  154. inviteFriendHandler(0,userChar,infoChar);
  155. }
  156. @end
  157. #pragma mark ============================>> unity call ios (声明unity call ios的托管函数 & 接收unity传过来的指针)
  158. /**
  159. * c语言字符串指针malloc
  160. */
  161. char* MakeStringCopy(const char* string){
  162. if (string == NULL)
  163. return NULL;
  164. char* res = (char*)malloc(strlen(string) + 1);
  165. strcpy(res, string);
  166. return res;
  167. }
  168. /**
  169. * unity call ios 主动接收 函数指针
  170. * MotionHandler 用于ios回调 "蓝牙动作",在👆🏻bridgingMotionAction中实现
  171. */
  172. extern "C" {void PointerMotionHandler(MotionHandler handler){
  173. motionHandler = handler;
  174. NSLog(@"PutIntPtr MotionHandler 指针内存地址 ===>> %p",&motionHandler);
  175. }
  176. }
  177. /**
  178. * unity call ios 主动接收 函数指针
  179. * StepHandler 用于ios回调 "鞋子步频",在👆🏻bridgingStepAction中实现
  180. */
  181. extern "C" { void PointerStepHandler(StepHandler handler){
  182. stepHandler = handler;
  183. NSLog(@"PutIntPtr StepHandler 指针内存地址 ===>> %p",&stepHandler);
  184. }
  185. }
  186. /**
  187. * unity call ios 主动接收 函数指针
  188. * StepHandler 用于ios回调 "鞋子蓝牙状态和电量",在👆🏻bridgingDeviceAction中实现
  189. */
  190. extern "C" {void PointerDeviceHandler(DeviceHandler handler){
  191. deviceHandler = handler;
  192. NSLog(@"PutIntPtr DeviceHandler 指针内存地址 ===>> %p",&deviceHandler);
  193. }
  194. }
  195. /**
  196. * unity call ios 主动接收 函数指针
  197. * ActionHandler 用于ios回调“”蓝牙和游戏大厅交互动作数据”,在👆🏻bridgingMotionAction中实现
  198. */
  199. extern "C" {void PointerActionHandler(ActionHandler handler){
  200. actionHandler = handler;
  201. NSLog(@"PutIntPtr UserFsHandler 指针内存地址 ===>> %p",&actionHandler);
  202. }
  203. }
  204. /**
  205. * unity call ios 主动接收 函数指针
  206. * UserFriendsHandler 用于ios回调 "当前用户好友列表",在👇🏻GetUserFriends中实现
  207. */
  208. extern "C" {void PointerUserFriendsHandler(UserFriendsHandler handler){
  209. userFriendsHandler = handler;
  210. NSLog(@"PutIntPtr UserFsHandler 指针内存地址 ===>> %p",&userFriendsHandler);
  211. }
  212. }
  213. /**
  214. * unity call ios 主动接收 函数指针
  215. * InviteFriendHandler 用于ios回调 "接收好友邀请" ,在👇🏻GetInviteInfo中实现
  216. */
  217. extern "C" {void PointerInviteFriendHandler(InviteFriendHandler handler){
  218. inviteFriendHandler = handler;
  219. NSLog(@"PutIntPtr UserFsHandler 指针内存地址 ===>> %p",&inviteFriendHandler);
  220. }
  221. }
  222. /**
  223. * unity call ios 主动接收 函数指针
  224. * InviteFriendHandler 用于ios回调 "接收好友邀请" ,在👇🏻GetInviteInfo中实现
  225. */
  226. extern "C" {void PointerGetRankHandler(GetRankHandler handler){
  227. getRankHandler = handler;
  228. NSLog(@"PutIntPtr GetRankHandler 指针内存地址 ===>> %p",&getRankHandler);
  229. }
  230. }
  231. /**
  232. * 游戏开始
  233. */
  234. void GameStart(){
  235. NSLog(@"Unity 请求开始游戏 GameStart ===>>");
  236. if ([instance existUserInfo]==NO){
  237. return;
  238. }
  239. //蓝牙
  240. [BTDataInstance gameStartInitData];
  241. //http
  242. [HTTPDataProcession gameStart];
  243. }
  244. /**
  245. * 游戏结束
  246. * level: level
  247. * score: score
  248. * record: record
  249. * mode: mode
  250. * opponentId: opponentId
  251. */
  252. void GameEnd(int level, double score, int record, int mode, int opponentId){
  253. NSLog(@"Unity 请求结束游戏 GameEnd ===>> %d %f %d %d %d",level,score,record,mode,opponentId);
  254. if ([instance existUserInfo]==NO){
  255. return;
  256. }
  257. [BTDataInstance gameEndInitData];
  258. //http
  259. [HTTPDataProcession gameEnd];
  260. //上传数据
  261. [HTTPDataProcession postGameRecord:level score:score record:record mode:mode opponentId:opponentId gameEndDataBlock:^(NSString *jsonString){
  262. NSLog(@"IOS_SKD 回调结束游戏请求 GameEnd ===> %@",jsonString);
  263. }];
  264. }
  265. /**
  266. * 搜索设备
  267. * type: 设备ID
  268. */
  269. void SearchDevice(int type){
  270. //unity 有两个search按钮 type 0是主设备 1是副设备
  271. NSLog(@"Unity 请求搜索设备 type ===>> %d",type);
  272. if ([instance existUserInfo]==NO){
  273. return;
  274. }
  275. [BTDataInstance searchBLEAction:type];
  276. }
  277. /**
  278. * 链接设备
  279. * type: 设备ID
  280. */
  281. void ConnectDevice(int type){
  282. NSLog(@"Unity 请求链接设备 ConnectDevice ===>> %d",type);
  283. if ([instance existUserInfo]==NO){
  284. return;
  285. }
  286. //unity 有两个connect按钮 type 0是第一个玩家 1是第二个玩家
  287. }
  288. /**
  289. * 震动
  290. * type: 设备ID
  291. * duration: 时长 ms [100 .. 1000]
  292. */
  293. void Vibrate(int type,int duration){
  294. if ([instance existUserInfo]==NO){
  295. return;
  296. }
  297. [BTDataInstance vibrationAction:type duration:duration];
  298. }
  299. /**
  300. * 震动
  301. * type: 设备ID
  302. * duration: 时长 ms [100 .. 1000]
  303. */
  304. void Vibrates(int type,int duration,int leftOrRight){
  305. if ([instance existUserInfo]==NO){
  306. return;
  307. }
  308. [BTDataInstance vibrationAction:type duration:duration];
  309. }
  310. /**
  311. * unity获取用户好友列表 -->> ios端根据用户token值请求http好友列表 ios将列表json的数组数据传给unity
  312. */
  313. void GetUserFriends(){
  314. // NSLog(@"Unity 请求好友列表 GetUserFriends ===>>");
  315. if ([instance existUserInfo]==NO){
  316. return;
  317. }
  318. [HTTPDataProcession getFriendsList:^(int code, const char *jsonString){
  319. NSLog(@"IOS_SKD 回调好友列表 GetUserFriends ===> %s",jsonString);
  320. userFriendsHandler(code,jsonString);//异步回调
  321. }];
  322. }
  323. /**
  324. * unity获取用户信息 -->> 解析从Spotr App的传过来的RL_Seme ios返回json数据给游戏
  325. */
  326. char * GetUserInfoJson(){
  327. // NSLog(@"Unity 请求用户信息 GetUserInfoJson ===>>");
  328. if ([instance existUserInfo]==NO){
  329. return MakeStringCopy("");
  330. }else{
  331. const char * cuschart = [[MYFactoryManager getUserInfo] UTF8String];
  332. NSLog(@"IOS_SKD 回调用户信息 GetUserInfoJson ===> %@",[MYFactoryManager getUserInfo]);
  333. //要先copy 不然c#调用free的时候回闪退
  334. return MakeStringCopy(cuschart);
  335. }
  336. }
  337. /**
  338. * unity可以主动断开链接
  339. * type: 设备类型 0: 主, 1: 副
  340. */
  341. void DisConnectDevice(int type){
  342. NSLog(@"Unity 请求断开蓝牙链接 disConnectDevice ===>>");
  343. if ([instance existUserInfo]==NO){
  344. return;
  345. }
  346. }
  347. /**
  348. * 主动邀请好友
  349. * friendid: 游戏好友ID
  350. */
  351. void InviteFriend(int friendid,char * info){
  352. NSLog(@"Unity 点击邀请好友 InviteFriend ===>>");
  353. if ([instance existUserInfo]==NO){
  354. return;
  355. }
  356. [HTTPDataProcession inviteFriends:friendid info:info inviteDataBlock:^(NSString *jsonString){
  357. // NSLog(@"IOS_SKD 回调点击邀请好友事件 InviteFriend ===>>");
  358. dispatch_async(dispatch_get_main_queue(), ^{
  359. [PopupView showCusHUDA:jsonString];
  360. });
  361. }];
  362. }
  363. /**
  364. * unity界面准备好后可以申请邀请信息,回调在inviteFriendHandler
  365. * friendid: 游戏好友ID
  366. */
  367. void GetInviteInfo(){
  368. NSLog(@"Unity获取好友邀请信息 GetInviteInfo ===>>");
  369. if ([instance existUserInfo]==NO){
  370. return;
  371. }
  372. //user字典 -> 字符串 -> Char
  373. const char * userChar = [[MYFactoryManager getInviteUser] UTF8String];
  374. //info字符串 -> Char
  375. const char * infoChar =[[MYFactoryManager getInviteInfo] UTF8String];
  376. NSLog(@"IOS_SKD 回调好友邀请信息 GetInviteInfo ===>> %s , %s",userChar,infoChar);
  377. inviteFriendHandler(0,userChar,infoChar);
  378. }
  379. /**
  380. * 投屏
  381. */
  382. void ScreenProjection(){
  383. NSLog(@"Unity 请求投屏事件 ScreenProjection ===>>");
  384. if ([instance existUserInfo]==NO){
  385. return;
  386. }
  387. }
  388. /**
  389. * Unity call ios 弹出邀请好友弹窗
  390. * 旧版游戏暂未用到
  391. */
  392. void ShowInviteFriend(int code, char * info){
  393. NSLog(@"Unity 请求打开好友列表弹窗 ShowInviteFriend ===>>");
  394. if ([instance existUserInfo]==NO){
  395. return;
  396. }
  397. }
  398. /**
  399. * Unity call ios 获取游戏榜单数据
  400. *if (type == 0) "world" else "friend"
  401. *ios 请求完数据后用 PointerGetRankHandler 回调数据给unity
  402. */
  403. void GetRank(int type){
  404. // NSLog(@"Unity 获取榜单列表数据 GetRank ===>> %d",type);
  405. if ([instance existUserInfo]==NO){
  406. return;
  407. }
  408. [HTTPDataProcession GetRank:type rankDataBlock:^(const char *jsonString){
  409. NSLog(@"IOS_SKD 回调 榜单列表数据 GetRank ===>> %d %s",type,jsonString);
  410. getRankHandler(type,jsonString);
  411. }];
  412. }
  413. /**
  414. * Unity call ios 获取鞋子角度
  415. */
  416. int NativeGetAttX(int cusId){
  417. return BTDataInstance.nativeAttX;
  418. }