/**************************************************************************** Copyright (c) 2010-2013 cocos2d-x.org Copyright (c) 2013-2016 Chukong Technologies Inc. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ #import "AppController.h" #import "cocos2d.h" #import "AppDelegate.h" #import "RootViewController.h" #import "SDKWrapper.h" #import "platform/ios/CCEAGLView-ios.h" #import #include "cocos/scripting/js-bindings/jswrapper/SeApi.h" #import #import "Reachability.h" #import "zhuanHuanM4a.h" #import "LineSDK/LineSDK-Swift.h" #import "AppleLoginManager.h" #import using namespace cocos2d; @implementation AppController Application* app = nullptr; @synthesize window; #pragma mark - #pragma mark Application lifecycle UIInterfaceOrientationMask orientation = UIInterfaceOrientationMaskLandscape; -(UIInterfaceOrientationMask) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ return orientation; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[SDKWrapper getInstance] application:application didFinishLaunchingWithOptions:launchOptions]; application.idleTimerDisabled=true; // Add the view controller's view to the window and display. float scale = [[UIScreen mainScreen] scale]; CGRect bounds = [[UIScreen mainScreen] bounds]; window = [[UIWindow alloc] initWithFrame: bounds]; // cocos2d application instance app = new AppDelegate(bounds.size.width * scale, bounds.size.height * scale); app->setMultitouch(true); Appself=self; // Use RootViewController to manage CCEAGLView _viewController = [[RootViewController alloc]init]; #ifdef NSFoundationVersionNumber_iOS_7_0 _viewController.automaticallyAdjustsScrollViewInsets = NO; _viewController.extendedLayoutIncludesOpaqueBars = NO; _viewController.edgesForExtendedLayout = UIRectEdgeAll; #else _viewController.wantsFullScreenLayout = YES; #endif // Set RootViewController to window if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0) { // warning: addSubView doesn't work on iOS6 [window addSubview: _viewController.view]; } else { // use this method on ios6 [window setRootViewController:_viewController]; } [window makeKeyAndVisible]; [[UIApplication sharedApplication] setStatusBarHidden:YES]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChanged:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; //run the cocos2d-x game scene app->start(); NSURL *unurl = [NSURL URLWithString:@"https://www.wangpaimj.com/line-auth"]; unurl=nil; [[LineSDKLoginManager sharedManager] setupWithChannelID:@"2008795912" universalLinkURL:unurl]; [[GIDSignIn sharedInstance] configureWithCompletion:^(NSError * _Nullable error) { if (error) { NSString *string = [NSString stringWithFormat:@"google config error: %@", error]; NSLog(@"%@", string); } else { NSLog(@"google config success"); } }]; return YES; } +(void) ChangeOrientation:(int) type { [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationUnknown] forKey:@"orientation"]; if(type == 0){ orientation = UIInterfaceOrientationMaskPortrait; [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationMaskPortrait] forKey:@"orientation"]; } else { orientation = UIInterfaceOrientationMaskLandscape; [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationMaskLandscape] forKey:@"orientation"]; } } +(void)initSDK:(NSString *)weiXinID weiXinSecret:(NSString *)weiXinSecret umKey:(NSString *)umKey amapKey:(NSString *)amapKey{ } #pragma mark - ----------------- 电池 -------------------- // +(NSNumber *)GetBatteryLv{ [UIDevice currentDevice].batteryMonitoringEnabled = YES; double deviceLevel = [UIDevice currentDevice].batteryLevel; NSString *str = [NSString stringWithFormat:@"%.2f", deviceLevel]; // NSLog(@"+++++++++++++++++++++++%@", str); return @([str floatValue]); } //////////////// - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return YES; } -(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { NSString *urlString = [url absoluteString]; NSLog(@"openURL: %@", urlString); // google if ([urlString hasPrefix:@"com.googleusercontent.apps"]) { return [[GIDSignIn sharedInstance] handleURL:url]; } // LINE if ([urlString hasPrefix:@"line3rdp"]) { return [[LineSDKLoginManager sharedManager] application:app open:url options:options]; } return NO; } #pragma mark - ----------------- 复制剪切板 -------------------- +(void)CopyClipper:(NSString *)str{ //msg UIPasteboard *board = [UIPasteboard generalPasteboard]; board.string = str; UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"" message:@"複製成功" delegate:nil cancelButtonTitle:@"確定" otherButtonTitles: nil]; [alert show]; } #pragma mark - ----------------- 打开url -------------------- +(void)OpenUrl:(NSString *)str{ NSURL *cleanURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@", str]]; [[UIApplication sharedApplication] openURL:cleanURL]; } // + (NSString *)isWifi { Reachability *reachability = [Reachability reachabilityWithHostName:@"www.apple.com"]; NetworkStatus internetStatus = [reachability currentReachabilityStatus]; NSString *net = @"WIFI"; switch (internetStatus) { case ReachableViaWiFi: net = @"WIFI"; return @"1"; break; case ReachableViaWWAN: net = @"蜂窩數據"; //net = [self getNetType ]; //判断具体类型 return @"0"; break; case NotReachable: net = @"當前無網路連接"; return @"0"; default: break; } return nil; } #pragma mark------------y录音 +(void)startRecord{ [[[self alloc] init] startVideo]; } - (void)startVideo{ NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"text.caf"]; // url : 录音文件的路径 (这里为便于测试,我用桌面路径,项目中需要用沙盒路径) NSURL *url = [NSURL URLWithString:path]; // setting:录音的设置项 NSDictionary *configDic = @{// 编码格式 AVFormatIDKey:@(kAudioFormatLinearPCM), // 采样率 AVSampleRateKey:@(8000), // 通道数 AVNumberOfChannelsKey:@(1), // 录音质量 AVEncoderAudioQualityKey:@(AVAudioQualityMin) }; NSError *error = nil; [[AVAudioSession sharedInstance] // 在创建recorder之前加上这两行,可以解决播放无声音的问题 setCategory:@"AVAudioSessionCategoryPlayAndRecord" error:nil]; [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil]; _record = [[AVAudioRecorder alloc]initWithURL:url settings:configDic error:&error]; if (error) { NSLog(@"error:%@",error); } // 准备录音(系统会给我们分配一些资源) [_record prepareToRecord]; [self.record record]; } +(NSString*)stopRecord:(NSString *)aaa{ NSString *str = [[[self alloc] init] stopVideo]; return str; } - (NSString *)stopVideo{ // if (self.record.currentTime > 2) { // [self.record stop]; // } else { // // 删除录音文件 // //如果想要删除录音文件,必须先停止录音 // [self.record stop]; // [self.record deleteRecording]; // } // NSLog(@"结束录音"); NSString *pathuLu = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"text.caf"]; NSString *path1 = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"aaaa.m4a"]; [zhuanHuanM4a convetCafToM4a:pathuLu destUrl:path1 completed:^(NSError * _Nonnull error) { NSData *mp3Data = [NSData dataWithContentsOfFile:path1]; NSString *data = [mp3Data base64Encoding]; std::string strRet1 = data == nil ?"": [data UTF8String]; std::string strRet = "onRecordFinish"; std::string jsCallStr = cocos2d::StringUtils::format("CallTableFunc(\"%s\",'%s');", strRet.c_str(),strRet1.c_str()); se::Value *ret = new se::Value(); se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret); NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"aaaa.m4a"]; NSFileManager*fileManager = [NSFileManager defaultManager]; [fileManager removeItemAtPath:path error:nil]; }]; return @"wait";///b6fe2012-ba85-49 } - (CGFloat)fileSize:(NSURL *)path { return [[NSData dataWithContentsOfURL:path] length]/1024.00 /1024.00; } +(void)playVoice:(NSString *)str{ [[[self alloc] init] playVoiceData:str]; } - (void)playVoiceData:(NSString *)data{ NSLog(@"!----------------------playVoiceData"); // Base64形式的字符串为data NSData *videoMy = [[NSData alloc] initWithBase64EncodedString:data options:NSDataBase64DecodingIgnoreUnknownCharacters]; AVAudioSession *audioSession = [AVAudioSession sharedInstance]; //默认情况下扬声器播放 [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; [audioSession setActive:YES error:nil]; self.player = [[AVAudioPlayer alloc] initWithData:videoMy error:nil]; self.player.numberOfLoops = 0; self.player.delegate = self; CGFloat currentVol = audioSession.outputVolume; //设置播放器声音 self.player.volume = currentVol; [self.player play]; } - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { std::string strRet = "OnPlayFinish"; std::string jsCallStr = cocos2d::StringUtils::format("CallTableFunc(\"%s\");", strRet.c_str()); se::Value *ret = new se::Value(); se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret); } //line 相关操作 + (void)sendLINELogin { [Appself lineLogin]; } + (void)sendAppleLogin { [Appself appleLogin]; } + (void)sendGoogleLogin { [Appself googleLogin]; } - (void)statusBarOrientationChanged:(NSNotification *)notification { CGRect bounds = [UIScreen mainScreen].bounds; float scale = [[UIScreen mainScreen] scale]; float width = bounds.size.width * scale; float height = bounds.size.height * scale; Application::getInstance()->updateViewSize(width, height); } - (void)applicationWillResignActive:(UIApplication *)application { /* Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. */ app->onPause(); [[SDKWrapper getInstance] applicationWillResignActive:application]; } - (void)applicationDidBecomeActive:(UIApplication *)application { /* Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. */ app->onResume(); [[SDKWrapper getInstance] applicationDidBecomeActive:application]; } - (void)applicationDidEnterBackground:(UIApplication *)application { /* Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. If your application supports background execution, called instead of applicationWillTerminate: when the user quits. */ [[SDKWrapper getInstance] applicationDidEnterBackground:application]; } - (void)applicationWillEnterForeground:(UIApplication *)application { /* Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. */ [[SDKWrapper getInstance] applicationWillEnterForeground:application]; } - (void)applicationWillTerminate:(UIApplication *)application { [[SDKWrapper getInstance] applicationWillTerminate:application]; delete app; app = nil; } #pragma mark - #pragma mark Memory management - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { /* Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. */ } + (void)GameClose:(NSString * _Nullable)aa { } #pragma mark - ----------------- 第三方登录 -------------------- - (void)appleLogin { AppleLoginManager *appleLoginManager = [[AppleLoginManager alloc] initWindow:Appself.window]; [appleLoginManager setOnAuthSuccess:^(NSString *token, NSString *nickname, NSString *userId) { [self evalParamStringWithToken:token nickname:nickname userId:userId sex:@"" headimgurl:@""]; }]; [appleLoginManager startAuthorization]; } - (void)lineLogin { NSSet *permissions = [NSSet setWithObjects: [LineSDKLoginPermission profile], [LineSDKLoginPermission openID], nil]; LineSDKLoginManagerParameters *parameters = [[LineSDKLoginManagerParameters alloc] init]; [[LineSDKLoginManager sharedManager] loginWithPermissions:permissions inViewController:Appself.viewController parameters:parameters completionHandler:^(LineSDKLoginResult *result, NSError *error) { if (error) { NSLog(@"LINE Login Error: %@", error); } else { NSString *token = result.accessToken.value ?: @""; NSString *nickname = result.userProfile.displayName ?: @""; NSString *userId = result.userProfile.userID ?: @""; NSString *headimgurl = result.userProfile.pictureURL.absoluteString ?: @""; [Appself evalParamStringWithToken:token nickname:nickname userId:userId sex:@"" headimgurl:headimgurl]; } } ]; } - (void)googleLogin { [[GIDSignIn sharedInstance] signInWithPresentingViewController:Appself.viewController completion:^(GIDSignInResult * _Nullable signInResult, NSError * _Nullable error) { if (error) { NSLog(@"google sign in error: %@", error); } else { [signInResult.user refreshTokensIfNeededWithCompletion:^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) { if (error || user == nil) { NSLog(@"google refreshTokens error: %@, user: %@", error, user); return; } GIDProfileData *profile = user.profile; NSString *headimgurl = [[profile imageURLWithDimension:100] absoluteString] ?: @""; [self evalParamStringWithToken:user.idToken.tokenString nickname:profile.name userId:user.userID sex:@"" headimgurl:headimgurl]; }]; } }]; } - (void)evalParamStringWithToken:(NSString *)token nickname:(NSString *)nickname userId:(NSString *)userId sex:(NSString *)sex headimgurl:(NSString *)headimgurl { NSString *jsonStr = [NSString stringWithFormat:@"{\"headimgurl\":\"%@\",\"sex\":\"%@\",\"unionid\":\"%@\",\"openid\":\"%@\",\"nickname\":\"%@\"}",headimgurl,sex,userId,token,nickname]; std::string paramsString = [jsonStr UTF8String]; std::string func = "onWXCode"; std::string name = [nickname UTF8String]; std::string jsCallStr = cocos2d::StringUtils::format("CallLoginFunc(\"%s\",'%s',\"%s\");", func.c_str(),paramsString.c_str(),name.c_str()); se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str()); } @end