// 
 | 
//  UniversalSDK.m 
 | 
//  Unity-iPhone 
 | 
// 
 | 
//  Created by 蔡瀚 on 2018/4/24. 
 | 
// 
 | 
  
 | 
#import "UniversalSDK.h" 
 | 
#import "JPUSHService.h" 
 | 
#import "AdSupport/AdSupport.h" 
 | 
#import "Tracking.h" 
 | 
#import "opus.h" 
 | 
#ifdef NSFoundationVersionNumber_iOS_9_x_Max 
 | 
#import <UserNotifications/UserNotifications.h> 
 | 
#endif 
 | 
#import "SystemConfiguration/CaptiveNetwork.h" 
 | 
#import <TTTracker/TTTracker+Game.h> 
 | 
#import <AoyouSDK/IVQNAoyouSDK.h> 
 | 
  
 | 
@interface UniversalSDK()<JPUSHRegisterDelegate,UIWebViewDelegate> 
 | 
@end 
 | 
  
 | 
@implementation UniversalSDK 
 | 
  
 | 
#define CHANNEL_NUM 1 
 | 
  
 | 
static int s_frequency = 16000; 
 | 
static int s_bitRate = 20000; 
 | 
static int s_bandMode = OPUS_BANDWIDTH_WIDEBAND; 
 | 
static int s_frameSize = 160; 
 | 
static int sBatteryLevel = -1; 
 | 
static int sBatteryState = -1; 
 | 
static NSString* sAppID; 
 | 
static NSString* sGameID; 
 | 
static NSString* sUserName; 
 | 
static NSThread* _thread; 
 | 
  
 | 
-(void) Init 
 | 
{ 
 | 
    NSString *_bundlePath = [[NSBundle mainBundle] pathForResource:@"The2thWorldRES.bundle" ofType:nil]; 
 | 
    NSString* _configPath = [[NSBundle bundleWithPath:_bundlePath] pathForResource:@"The2thWorldSDKConfig" ofType:@"plist"]; 
 | 
    NSMutableDictionary *_configDict = [[NSMutableDictionary alloc] initWithContentsOfFile:_configPath]; 
 | 
     
 | 
    UIDevice *_device = [UIDevice currentDevice]; 
 | 
    _device.batteryMonitoringEnabled = true; 
 | 
     
 | 
    NSString* _uniqueID = [[NSUserDefaults standardUserDefaults] objectForKey:@"tsw_unique_id"]; 
 | 
    //获取IDFA 
 | 
    NSString* _idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; 
 | 
     
 | 
    if(_uniqueID == NULL || [_uniqueID length] <= 0) 
 | 
    { 
 | 
        //判断IDFA是否为空 
 | 
        BOOL isEmpty = [[_idfa stringByReplacingOccurrencesOfString:@"-" withString:@""] stringByReplacingOccurrencesOfString:@"0" withString:@""].length; 
 | 
        if (isEmpty) { 
 | 
            //不为空,将IDFA作为唯一标识 
 | 
            _uniqueID = _idfa; 
 | 
        } 
 | 
        else { 
 | 
            //为空,获取UUID作为唯一标识 
 | 
            _uniqueID = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; 
 | 
        } 
 | 
         
 | 
        //保存唯一设备标识,如已存在则不进行任何处理 
 | 
        [[NSUserDefaults standardUserDefaults] setObject:_uniqueID forKey:@"tsw_unique_id"]; 
 | 
        [[NSUserDefaults standardUserDefaults] synchronize]; 
 | 
    } 
 | 
     
 | 
    // 取得UserAgent 
 | 
    UIWebView* _webView = [[UIWebView alloc] initWithFrame:CGRectZero]; 
 | 
    NSString* _userAgent = [_webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]; 
 | 
     
 | 
    // 发送设备信息 
 | 
    NSMutableDictionary *_dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
 | 
                                  _uniqueID,@"unique_id", 
 | 
                                  _idfa,@"android_id", 
 | 
                                  [NSNumber numberWithInt:S2U_DeviceInfo],@"code", 
 | 
                                  _userAgent,@"userAgent",nil]; 
 | 
    [self SendMessageToUnity:_dict]; 
 | 
     
 | 
    // 发送个推id 
 | 
    [_dict removeAllObjects]; 
 | 
    [_dict setObject:[JPUSHService registrationID] forKey:@"clientID"]; 
 | 
    [_dict setObject:[NSNumber numberWithInt:S2U_PushClientID] forKey:@"code"]; 
 | 
    [self SendMessageToUnity:_dict]; 
 | 
     
 | 
    // 热云初始化 
 | 
    [Tracking initWithAppKey:_configDict[@"TrackingIO_AppKey"] 
 | 
               withChannelId:@"_default_"]; 
 | 
     
 | 
    // 今日头条 
 | 
    NSDictionary* _infoDictionary = [[NSBundle mainBundle] infoDictionary]; 
 | 
    [TTTracker startWithAppID:_configDict[@"TTTrack_AppID"] 
 | 
                      channel:@"ios-xbqy" 
 | 
                      appName:[_infoDictionary objectForKey:@"CFBundleDisplayName"]]; 
 | 
     
 | 
    // 发送初始化完成 
 | 
    [_dict removeAllObjects]; 
 | 
    [_dict setObject:[NSNumber numberWithInt:S2U_SdkInitComplete] forKey:@"code"]; 
 | 
    [_dict setObject:@"yl" forKey:@"channelPlatform"]; 
 | 
    [self SendMessageToUnity:_dict]; 
 | 
} 
 | 
  
 | 
-(void)SendMessageToUnity:(NSDictionary*)dict 
 | 
{ 
 | 
    BOOL _result = [NSJSONSerialization isValidJSONObject:dict]; 
 | 
    if(_result) 
 | 
    { 
 | 
        NSData* _jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:NULL]; 
 | 
        UnitySendMessage(UNITY_OBJ_NAME, UNITY_FUNC_NAME, 
 | 
                         [[[NSString alloc] initWithData:_jsonData encoding:NSUTF8StringEncoding] UTF8String]); 
 | 
    } 
 | 
} 
 | 
  
 | 
-(void) BatteryThread { 
 | 
    while (TRUE) 
 | 
    { 
 | 
        [NSThread sleepForTimeInterval:1]; 
 | 
         
 | 
        UIDevice *_device = [UIDevice currentDevice]; 
 | 
         
 | 
        int _state = [_device batteryState]; 
 | 
        if(_state != sBatteryState){ 
 | 
            sBatteryState = _state; 
 | 
            NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: 
 | 
                                   [NSNumber numberWithInt:sBatteryState], @"status", 
 | 
                                   [NSNumber numberWithInt:S2U_BatteryCharging], @"code", nil]; 
 | 
             
 | 
            [self SendMessageToUnity:_dict]; 
 | 
        } 
 | 
         
 | 
        int _level = (int)([_device batteryLevel] * 100); 
 | 
        if(_level != sBatteryLevel){ 
 | 
            sBatteryLevel = _level; 
 | 
            NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: 
 | 
                                   [NSNumber numberWithInt:sBatteryLevel], @"level", 
 | 
                                   [NSNumber numberWithInt:S2U_BatteryLevel], @"code", nil]; 
 | 
             
 | 
            [self SendMessageToUnity:_dict]; 
 | 
        } 
 | 
    } 
 | 
} 
 | 
  
 | 
-(void) OpenURL:(NSString*) url { 
 | 
     
 | 
    if(m_UIWebView != NULL) { 
 | 
        [self btnClick:NULL]; 
 | 
        return; 
 | 
    } 
 | 
     
 | 
    CGRect _bounds = UnityGetMainWindow().bounds; 
 | 
     
 | 
    float _scale = _bounds.size.width / 1334; 
 | 
     
 | 
    float _width = 982 * _scale; 
 | 
    float _height = 560 * _scale; 
 | 
     
 | 
    float _offsetX = (_bounds.size.width - _width) * .5f; 
 | 
    float _offsetY = (_bounds.size.height - _height) * .5f; 
 | 
     
 | 
    m_UIWebView = [[UIWebView alloc] initWithFrame:CGRectMake(_offsetX, _offsetY, _width, _height)]; 
 | 
    m_UIWebView.delegate = self; 
 | 
    m_UIWebView.scalesPageToFit = YES ; 
 | 
    m_UIWebView.scrollView.scrollEnabled = YES; 
 | 
    m_UIWebView.scrollView.bounces = NO; 
 | 
    NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:url]]; 
 | 
    [m_UIWebView loadRequest:request]; 
 | 
} 
 | 
  
 | 
-(void) btnClick:(UIButton*)sender { 
 | 
    [m_CloseBtn removeFromSuperview]; 
 | 
    [m_CloseBtn removeTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; 
 | 
    m_CloseBtn = NULL; 
 | 
     
 | 
    NSURLCache *_cache = [NSURLCache sharedURLCache]; 
 | 
    [_cache removeAllCachedResponses]; 
 | 
    [_cache setDiskCapacity:0]; 
 | 
    [_cache setMemoryCapacity:0]; 
 | 
     
 | 
    [m_UIWebView removeFromSuperview]; 
 | 
    m_UIWebView = NULL; 
 | 
} 
 | 
  
 | 
-(void)webViewDidStartLoad:(UIWebView *)webView{ 
 | 
} 
 | 
  
 | 
-(void)webViewDidFinishLoad:(UIWebView *)webView{ 
 | 
     
 | 
    [UnityGetMainWindow().rootViewController.view addSubview:m_UIWebView]; 
 | 
    CGRect _bounds = UnityGetMainWindow().bounds; 
 | 
     
 | 
    float _scale = _bounds.size.width / 1334; 
 | 
     
 | 
    float _width = 982 * _scale; 
 | 
    float _height = 560 * _scale; 
 | 
     
 | 
    m_CloseBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
 | 
    [m_CloseBtn setFrame:CGRectMake(_width - 455 * _scale, _height - 86 * _scale, 180 * _scale, 72 * _scale)]; 
 | 
    [m_CloseBtn setTitle:@"我知道了" forState:UIControlStateNormal]; 
 | 
     
 | 
    NSString *_bundlePath = [[NSBundle mainBundle] pathForResource:@"The2thWorldRES.bundle" ofType:nil]; 
 | 
    NSBundle *_bundle = [NSBundle bundleWithPath:_bundlePath]; 
 | 
    NSString *pic1Path = [_bundle pathForResource:@"TY_AN_34.png" ofType:nil]; 
 | 
     
 | 
    [m_CloseBtn setBackgroundImage:[UIImage imageWithContentsOfFile:pic1Path] forState:UIControlStateNormal]; 
 | 
    [m_CloseBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 
 | 
    [m_CloseBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; 
 | 
     
 | 
    [m_UIWebView addSubview:m_CloseBtn]; 
 | 
} 
 | 
  
 | 
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ 
 | 
} 
 | 
  
 | 
-(void)JPushInit:(NSDictionary*)launchOptions { 
 | 
     
 | 
     
 | 
    NSString *_bundlePath = [[NSBundle mainBundle] pathForResource:@"The2thWorldRES.bundle" ofType:nil]; 
 | 
    NSString* _configPath = [[NSBundle bundleWithPath:_bundlePath] pathForResource:@"The2thWorldSDKConfig" ofType:@"plist"]; 
 | 
    NSMutableDictionary *_configDict = [[NSMutableDictionary alloc] initWithContentsOfFile:_configPath]; 
 | 
     
 | 
    JPUSHRegisterEntity *_entity = [[JPUSHRegisterEntity alloc] init]; 
 | 
    _entity.types = JPAuthorizationOptionAlert | JPAuthorizationOptionBadge | JPAuthorizationOptionSound; 
 | 
    if([[UIDevice currentDevice].systemVersion floatValue] > 8.0){ 
 | 
    } 
 | 
     
 | 
    [JPUSHService registerForRemoteNotificationConfig:_entity 
 | 
                                             delegate:self]; 
 | 
    [JPUSHService setupWithOption:launchOptions 
 | 
                           appKey:_configDict[@"JPush_AppKey"] 
 | 
                          channel:@"develop" 
 | 
                 apsForProduction:JPush_IsProduction 
 | 
            advertisingIdentifier:nil]; 
 | 
} 
 | 
  
 | 
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { 
 | 
     
 | 
    NSDictionary * userInfo = response.notification.request.content.userInfo; 
 | 
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { 
 | 
        [JPUSHService handleRemoteNotification:userInfo]; 
 | 
    } 
 | 
    completionHandler(); 
 | 
} 
 | 
  
 | 
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler { 
 | 
     
 | 
    NSDictionary * userInfo = notification.request.content.userInfo; 
 | 
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { 
 | 
        [JPUSHService handleRemoteNotification:userInfo]; 
 | 
    } 
 | 
    completionHandler(UNNotificationPresentationOptionAlert); 
 | 
} 
 | 
  
 | 
-(id) APNativeJSONObject:(NSData *)data{ 
 | 
    if (!data) { 
 | 
        return nil; 
 | 
    } 
 | 
     
 | 
    NSError *error = nil; 
 | 
    id retId = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 
 | 
     
 | 
    if (error) { 
 | 
        NSLog(@"%s trans data to obj with error: %@", __func__, error); 
 | 
        return nil; 
 | 
    } 
 | 
     
 | 
    return retId; 
 | 
} 
 | 
  
 | 
-(NSData *)APNativeJSONData:(id)obj { 
 | 
    NSError *error = nil; 
 | 
    NSData *data = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&error]; 
 | 
    if (error) { 
 | 
        NSLog(@"%s trans obj to data with error: %@", __func__, error); 
 | 
        return nil; 
 | 
    } 
 | 
    return data; 
 | 
} 
 | 
  
 | 
-(void) RemoveLocalNotificationWithIdentifierKey:(NSString*) idKey{ 
 | 
    JPushNotificationIdentifier *identifier = [[JPushNotificationIdentifier alloc] init]; 
 | 
    identifier.identifiers = @[idKey]; 
 | 
    identifier.delivered = YES;  //iOS10以上有效,等于YES则在通知中心显示的里面移除,等于NO则为在待推送的里面移除;iOS10以下无效 
 | 
    [JPUSHService removeNotification:identifier]; 
 | 
} 
 | 
  
 | 
-(void)HandleUnityMessage:(NSString *)json { 
 | 
     
 | 
    NSLog(@"收到Unity发来的消息 => %@", json); 
 | 
     
 | 
    NSData *_jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; 
 | 
    NSDictionary *_dict = [self APNativeJSONObject:_jsonData]; 
 | 
     
 | 
    switch([[_dict objectForKey:@"code"] intValue]){ 
 | 
        case U2S_Init: 
 | 
            [self Init]; 
 | 
            sAppID = _dict[@"appID"]; 
 | 
            sGameID = _dict[@"gameID"]; 
 | 
            break; 
 | 
        case U2S_CopyContent: 
 | 
            [UIPasteboard generalPasteboard].string = _dict[@"content"]; 
 | 
            break; 
 | 
        case U2S_FreePlatformInit: 
 | 
            break; 
 | 
        case U2S_MakeKeyAndVisible: 
 | 
        { 
 | 
            UIWindow * _window = [[UIApplication sharedApplication].delegate window]; 
 | 
            if (_window != nil && _window.rootViewController != nil) { 
 | 
                [_window makeKeyAndVisible]; 
 | 
            } 
 | 
        } 
 | 
            break; 
 | 
        case U2S_OpenWebView: 
 | 
            [self OpenURL:_dict[@"url"]]; 
 | 
            break; 
 | 
        case U2S_FreePlatformLogin: 
 | 
        { 
 | 
            [IVQNAoyouSDK ETTTloadLoginingVCResultSuccess:^(NSString * _Nonnull loginTime, NSString * _Nonnull userName, NSString * _Nonnull sign) { 
 | 
                NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: 
 | 
                                       [NSDictionary dictionaryWithObjectsAndKeys:sign, @"token", 
 | 
                                        [NSString stringWithFormat:@"%@",loginTime], @"token_expire", 
 | 
                                        userName, @"account", nil],@"info", 
 | 
                                       [NSNumber numberWithInt:S2U_FreePlatformLoginOk], @"code", nil]; 
 | 
                sUserName = userName; 
 | 
                [self SendMessageToUnity:_dict]; 
 | 
            } failed:^(NSInteger code, NSString * _Nonnull message) { 
 | 
                NSLog(@"登录失败: code=%zd, msg=%@",code,message); 
 | 
            }]; 
 | 
        } 
 | 
            break; 
 | 
        case U2S_FreePlatformLogout: 
 | 
        { 
 | 
            [IVQNAoyouSDK ETTTloadLoginingVCResultSuccess:^(NSString * _Nonnull loginTime, NSString * _Nonnull userName, NSString * _Nonnull sign) { 
 | 
                NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: 
 | 
                                       [NSDictionary dictionaryWithObjectsAndKeys:sign, @"token", 
 | 
                                        [NSString stringWithFormat:@"%@",loginTime], @"token_expire", 
 | 
                                        userName, @"account", nil],@"info", 
 | 
                                       [NSNumber numberWithInt:S2U_FreePlatformLoginOk], @"code", nil]; 
 | 
                sUserName = userName; 
 | 
                [self SendMessageToUnity:_dict]; 
 | 
            } failed:^(NSInteger code, NSString * _Nonnull message) { 
 | 
                NSLog(@"登录失败: code=%zd, msg=%@",code,message); 
 | 
            }]; 
 | 
        } 
 | 
            break; 
 | 
        case U2S_RoleLogin: 
 | 
            [IVQNAoyouSDK NFEGSetUserInfoWithRoleId:[NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]] 
 | 
                                           roleName:[_dict objectForKey:@"roleName"] 
 | 
                                          roleLevel:[NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]] 
 | 
                                             zoneId:[NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]] 
 | 
                                           zoneName:[_dict objectForKey:@"serverName"] 
 | 
                                             attach:@"" 
 | 
                                              block:^(NSInteger code) { 
 | 
                                                  NSLog(@"---- code: %zd",code); 
 | 
                                              }]; 
 | 
            break; 
 | 
        case U2S_FreePlatformPay: 
 | 
        { 
 | 
            [IVQNAoyouSDK KPTBloadToFQVCWithRoleid:[_dict objectForKey:@"roleID"] 
 | 
                                                mo:[_dict objectForKey:@"mount"] 
 | 
                                          serverid:[_dict objectForKey:@"sid"] 
 | 
                                       productName:[_dict objectForKey:@"title"] 
 | 
                                       productDesc:[_dict objectForKey:@"title"] 
 | 
                                            attach:[NSString stringWithFormat:@"{\"appid\":\"%@\",\"cpinfo\":\"%@\",\"cporderid\":\"%@\",\"productid\":\"%@\"}", 
 | 
                                                    sAppID, 
 | 
                                                    [_dict objectForKey:@"cpInfo"], 
 | 
                                                    [_dict objectForKey:@"orderId"], 
 | 
                                                    sGameID] 
 | 
                                         productId:[_dict objectForKey:@"cpInfo"] 
 | 
                                           success:^(NSString * _Nonnull message, NSString * _Nonnull money) { 
 | 
                                               NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: 
 | 
                                                                      [NSNumber numberWithInt:S2U_FreePlatformPayOk], @"code", nil]; 
 | 
                                               [self SendMessageToUnity:_dict]; 
 | 
                                           } faild:^(NSString * _Nonnull message, NSInteger code, NSString * _Nonnull money) { 
 | 
                                               NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: 
 | 
                                                                      [NSNumber numberWithInt:S2U_FreePlatformPayFail], @"code", nil]; 
 | 
                                               [self SendMessageToUnity:_dict]; 
 | 
                                           }]; 
 | 
        } 
 | 
            break; 
 | 
        case U2S_PayFinished: 
 | 
            [Tracking setRyzf:[_dict objectForKey:@"orderID"] 
 | 
                     ryzfType:[_dict objectForKey:@"payType"] 
 | 
                       hbType:[_dict objectForKey:@"moneyType"] 
 | 
                     hbAmount:[_dict[@"money"] floatValue]]; 
 | 
             
 | 
            [TTTracker purchaseEventWithContentType:@"mingwen" 
 | 
                                        contentName:@"yuanbao" 
 | 
                                          contentID:[_dict objectForKey:@"orderID"] 
 | 
                                      contentNumber:1 
 | 
                                     paymentChannel:@"_defaul_" 
 | 
                                           currency:@"rmb" 
 | 
                                    currency_amount:[_dict[@"money"] intValue] 
 | 
                                          isSuccess:true]; 
 | 
            break; 
 | 
        case U2S_BatteryListenStart: 
 | 
            if(_thread == NULL) 
 | 
            { 
 | 
                _thread = [[NSThread alloc] initWithTarget:self selector:@selector(BatteryThread) object:nil]; 
 | 
                [_thread setName:@"BatteryCheck"]; 
 | 
            } 
 | 
            if(![_thread isExecuting]) 
 | 
            { 
 | 
                [_thread start]; 
 | 
            } 
 | 
            break; 
 | 
        case U2S_BatteryListenStop: 
 | 
            break; 
 | 
        case U2S_SendRegistEvent: 
 | 
            [Tracking setRegisterWithAccountID:sUserName]; 
 | 
            [TTTracker registerEventByMethod:@"_default_" isSuccess:true]; 
 | 
            break; 
 | 
        case U2S_SendLoginEvent: 
 | 
            [Tracking setLoginWithAccountID:sUserName]; 
 | 
            [TTTracker loginEventByMethod:@"_default_" isSuccess:true]; 
 | 
            break; 
 | 
        case U2S_JPushRemoveLocalMessage: 
 | 
            [self RemoveLocalNotificationWithIdentifierKey:_dict[@"id"]]; 
 | 
            break; 
 | 
        case U2S_JPushAddLocalMessage: 
 | 
        { 
 | 
            JPushNotificationContent *_content = [[JPushNotificationContent alloc] init]; 
 | 
            if (_dict[@"title"]) { 
 | 
                _content.title = _dict[@"title"]; 
 | 
            } 
 | 
            if (_dict[@"subtitle"]) { 
 | 
                _content.subtitle = _dict[@"subtitle"]; 
 | 
            } 
 | 
            if (_dict[@"content"]) { 
 | 
                _content.body = _dict[@"content"]; 
 | 
            } 
 | 
            if (_dict[@"badge"]) { 
 | 
                _content.badge = @([_dict[@"badge"] intValue]); 
 | 
            } 
 | 
            if (_dict[@"action"]) { 
 | 
                _content.action = _dict[@"action"]; 
 | 
            } 
 | 
            if (_dict[@"extra"]) { 
 | 
                _content.userInfo = _dict[@"extra"]; 
 | 
            } 
 | 
            if (_dict[@"sound"]) { 
 | 
                _content.sound = _dict[@"sound"]; 
 | 
            } 
 | 
            JPushNotificationTrigger *_trigger = [[JPushNotificationTrigger alloc] init]; 
 | 
            if (_dict[@"fireTime"]) { 
 | 
                long _time = [_dict[@"fireTime"] longValue]; 
 | 
                NSNumber *date = @(_time); 
 | 
                if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) { 
 | 
                    NSTimeInterval currentInterval = [[NSDate date] timeIntervalSince1970]; 
 | 
                    NSTimeInterval interval = [date doubleValue] - currentInterval; 
 | 
                    interval = interval > 0? interval : 0; 
 | 
                    _trigger.timeInterval = interval; 
 | 
                } else { 
 | 
                    _trigger.fireDate = [NSDate dateWithTimeIntervalSince1970: [date doubleValue]]; 
 | 
                } 
 | 
                JPushNotificationRequest *_request = [[JPushNotificationRequest alloc] init]; 
 | 
                _request.requestIdentifier = [NSString stringWithFormat:@"%@",_dict[@"id"]]; 
 | 
                _request.content = _content; 
 | 
                _request.trigger = _trigger; 
 | 
                _request.completionHandler = ^(id result) { 
 | 
                    // iOS10以上成功则result为UNNotificationRequest对象,失败则result为nil;iOS10以下成功result为UILocalNotification对象,失败则result为nil 
 | 
                    NSLog(@"结果返回:%@", result); 
 | 
                }; 
 | 
                [JPUSHService addNotification:_request]; 
 | 
                break; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
} 
 | 
@end 
 | 
  
 | 
extern "C" void native_opus_init(int frequency, int bitRate, int bandMode) 
 | 
{ 
 | 
    s_frequency = frequency; 
 | 
    s_bandMode = bandMode; 
 | 
    s_bitRate = bitRate; 
 | 
    s_frameSize = frequency / 100; 
 | 
} 
 | 
  
 | 
extern "C" int native_opus_encode(opus_int16 *pcm, int len, unsigned char *opus) 
 | 
{ 
 | 
    int errorCode = 0; 
 | 
    opus_int32 skip = 0; 
 | 
    OpusEncoder *enc = opus_encoder_create(s_frequency, CHANNEL_NUM, OPUS_APPLICATION_VOIP, &errorCode); 
 | 
    if (OPUS_OK != errorCode) { 
 | 
        enc = NULL; 
 | 
        return -1; 
 | 
    } 
 | 
     
 | 
    opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(s_bandMode)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_BITRATE(s_bitRate)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_VBR(1)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_SIGNAL_VOICE)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_DTX(0)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0)); 
 | 
    opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip)); 
 | 
    opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16)); 
 | 
     
 | 
    unsigned char *rbytes = opus; 
 | 
    opus_int16 *frame = pcm; 
 | 
    int totalSize = 0; 
 | 
    while (len >= s_frameSize) 
 | 
    { 
 | 
        opus_int32 length = opus_encode(enc, frame, s_frameSize, rbytes + sizeof(char), s_bitRate); 
 | 
        rbytes[0] = length; 
 | 
        frame += s_frameSize; 
 | 
        rbytes += length + sizeof(char); 
 | 
        len -= s_frameSize; 
 | 
        totalSize += length; 
 | 
    } 
 | 
    opus_encoder_destroy(enc); 
 | 
    return totalSize; 
 | 
} 
 | 
  
 | 
extern "C" int native_opus_decode(unsigned char *opus, int len, short *pcm) 
 | 
{ 
 | 
    int err = 0; 
 | 
    //opus_int32 skip = 0; 
 | 
     
 | 
    OpusDecoder *dec = opus_decoder_create(s_frequency, CHANNEL_NUM, &err); 
 | 
    if (err != OPUS_OK) { 
 | 
        dec = NULL; 
 | 
        return -1; 
 | 
    } 
 | 
     
 | 
    while (len > 0) 
 | 
    { 
 | 
        int frame_opus_length = opus[0]; 
 | 
        int length = opus_decode(dec, opus + sizeof(char), frame_opus_length, pcm, s_frameSize, 0); 
 | 
        opus += sizeof(char) + frame_opus_length; 
 | 
        pcm += s_frameSize; 
 | 
        len = len - frame_opus_length - sizeof(char); 
 | 
    } 
 | 
    opus_decoder_destroy(dec); 
 | 
    return 0; 
 | 
} 
 |