天天看點

Unity2018接入高德地圖

首先需要的是安裝 pods,具體參考

https://www.cnblogs.com/sasuke6/p/4724116.html

https://www.jianshu.com/p/1bb0ad42cb2e

// 安裝pods
sudo gem install cocoapods

// 在項目路徑初始化
pod init

// 搜尋相關的包
pod search

// 安裝
pod install
           

Podfile 高德地圖檔案配置

# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'

target 'Unity-iPhone' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  use_frameworks!
  pod 'AMapLocation-NO-IDFA'

  # Pods for Unity-iPhone

  # target 'Unity-iPhone Tests' do
  #   inherit! :search_paths
  #   # Pods for testing
  # end

end

           

項目配置

Unity2018接入高德地圖

這2個 framework直接拷貝到 Unity項目的 /Plugins/iOS/ 目錄下,然後按照官方文檔把相關的依賴庫導進去

項目檔案入口 UnityAppController.h

#pragma once

#import <QuartzCore/CADisplayLink.h>

#include "PluginBase/RenderPluginDelegate.h"
#include "WXApi.h"
#include "WXApiManager.h"

#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapLocationKit/AMapLocationKit.h>

#define DefaultLocationTimeout 10
#define DefaultReGeocodeTimeout 5





@class UnityView;
@class UnityViewControllerBase;
@class DisplayConnection;

@interface UnityAppController : NSObject<UIApplicationDelegate,WXApiDelegate,AMapLocationManagerDelegate>
{

//    AMapLocatingCompletionBlock completionBlock;
//    AMapLocationManager *locationManager;
    
    UnityView*          _unityView;
    CADisplayLink*      _displayLink;

    UIWindow*           _window;
    UIView*             _rootView;
    UIViewController*   _rootController;
    UIView*             _snapshotView;

    DisplayConnection*  _mainDisplay;

    // We will cache view controllers used for fixed orientation (indexed by UIInterfaceOrientation).
    // Default view contoller goes to index 0. The default view controller is used when autorotation is enabled.
    //
    // There's no way to force iOS to change orientation when autorotation is enabled and the current orientation is disabled.
    // [UIViewController attemptRotationToDeviceOrientation] is insufficient to force iOS to change orientation in this circumstance.
    // We will recreate _viewControllerForOrientation[0] in that case immediately (see checkOrientationRequest for more comments)
#if UNITY_SUPPORT_ROTATION
    UIViewController*       _viewControllerForOrientation[5];
    UIInterfaceOrientation  _curOrientation;
#else
    UIViewController*       _viewControllerForOrientation[1];
#endif

    id<RenderPluginDelegate>    _renderDelegate;
}

// override it to add your render plugin delegate
- (void)shouldAttachRenderDelegate;

// this one is called at the very end of didFinishLaunchingWithOptions:
// after views have been created but before initing engine itself
// override it to register plugins, tweak UI etc
- (void)preStartUnity;

// this one is called at first applicationDidBecomeActive
// NB: it will be started with delay 0, so it will run on next run loop iteration
// this is done to make sure that activity indicator animation starts before blocking loading
- (void)startUnity:(UIApplication*)application;

// this is a part of UIApplicationDelegate protocol starting with ios5

// 高德地圖
@property (nonatomic, strong) AMapLocationManager *locationManager;
@property (nonatomic, copy) AMapLocatingCompletionBlock completionBlock;


// setter will be generated empty
@property (retain, nonatomic) UIWindow* window;

@property (readonly, copy, nonatomic) UnityView*            unityView;
@property (readonly, copy, nonatomic) CADisplayLink*        unityDisplayLink;

@property (readonly, copy, nonatomic) UIView*               rootView;
@property (readonly, copy, nonatomic) UIViewController*     rootViewController;
@property (readonly, copy, nonatomic) DisplayConnection*    mainDisplay;

#if UNITY_SUPPORT_ROTATION
@property (readonly, nonatomic) UIInterfaceOrientation      interfaceOrientation;
#endif

@property (nonatomic, retain) id                            renderDelegate;
@property (nonatomic, copy)                                 void(^quitHandler)();

@end

// accessing app controller

extern UnityAppController* _UnityAppController;
inline UnityAppController* GetAppController()
{
    return _UnityAppController;
}

// Put this into mm file with your subclass implementation
// pass subclass name to define

#define IMPL_APP_CONTROLLER_SUBCLASS(ClassName) \
@interface ClassName(OverrideAppDelegate)       \
{                                               \
}                                               \
+(void)load;                                    \
@end                                            \
@implementation ClassName(OverrideAppDelegate)  \
+(void)load                                     \
{                                               \
    extern const char* AppControllerClassName;  \
    AppControllerClassName = #ClassName;        \
}                                               \
@end                                            \


// plugins

#define APP_CONTROLLER_RENDER_PLUGIN_METHOD(method)                         \
do {                                                                        \
    id<RenderPluginDelegate> delegate = GetAppController().renderDelegate;  \
    if([delegate respondsToSelector:@selector(method)])                     \
        [delegate method];                                                  \
} while(0)

#define APP_CONTROLLER_RENDER_PLUGIN_METHOD_ARG(method, arg)                \
do {                                                                        \
    id<RenderPluginDelegate> delegate = GetAppController().renderDelegate;  \
    if([delegate respondsToSelector:@selector(method:)])                    \
        [delegate method:arg];                                              \
} while(0)


// these are simple wrappers about ios api, added for convenience
void AppController_SendNotification(NSString* name);
void AppController_SendNotificationWithArg(NSString* name, id arg);

void AppController_SendUnityViewControllerNotification(NSString* name);

// in the case when apple adds new api that has easy fallback path for old ios
// we will add new api methods at runtime on older ios, so we can switch to new api universally
// in that case we still need actual declaration: we do it here as most convenient place

#if (PLATFORM_IOS && !UNITY_HAS_IOSSDK_10_0) || (PLATFORM_TVOS && !UNITY_HAS_TVOSSDK_10_0)
@interface CADisplayLink ()
@property(nonatomic) NSInteger preferredFramesPerSecond;
@end
#endif

#if (PLATFORM_IOS && !UNITY_HAS_IOSSDK_10_3) || (PLATFORM_TVOS && !UNITY_HAS_TVOSSDK_10_2)
// The maximumFramesPerSecond API is available in the SDKs since 10.3.
// However, tvOS SDK has it already in 10.2, but disabled.
@interface UIScreen ()
@property (readonly) NSInteger maximumFramesPerSecond;
@end
#endif

#if (PLATFORM_IOS && !UNITY_HAS_IOSSDK_11_0) || (PLATFORM_TVOS && !UNITY_HAS_TVOSSDK_11_0)
// The safeAreaInsets API is available in the SDKs since 11.0.
@interface UIView ()
@property (nonatomic, readonly) UIEdgeInsets safeAreaInsets;
@end
#endif

           

項目檔案入口 UnityAppController.mm

#import "UnityAppController.h"
#import "UnityAppController+ViewHandling.h"
#import "UnityAppController+Rendering.h"
#import "iPhone_Sensors.h"

#import <CoreGraphics/CoreGraphics.h>
#import <QuartzCore/QuartzCore.h>
#import <QuartzCore/CADisplayLink.h>
#import <Availability.h>

#import <OpenGLES/EAGL.h>
#import <OpenGLES/EAGLDrawable.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>

#include <mach/mach_time.h>

// MSAA_DEFAULT_SAMPLE_COUNT was moved to iPhone_GlesSupport.h
// ENABLE_INTERNAL_PROFILER and related defines were moved to iPhone_Profiler.h
// kFPS define for removed: you can use Application.targetFrameRate (30 fps by default)
// DisplayLink is the only run loop mode now - all others were removed

#include "CrashReporter.h"

#include "UI/OrientationSupport.h"
#include "UI/UnityView.h"
#include "UI/Keyboard.h"
#include "UI/SplashScreen.h"
#include "Unity/InternalProfiler.h"
#include "Unity/DisplayManager.h"
#include "Unity/EAGLContextHelper.h"
#include "Unity/GlesHelper.h"
#include "Unity/ObjCRuntime.h"
#include "PluginBase/AppDelegateListener.h"

#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>

#include "SystemPermissionsManager.h"
#include "BrowserViewController.h"


// we assume that app delegate is never changed and we can cache it, instead of re-query UIApplication every time
UnityAppController* _UnityAppController = nil;

// Standard Gesture Recognizers enabled on all iOS apps absorb touches close to the top and bottom of the screen.
// This sometimes causes an ~1 second delay before the touch is handled when clicking very close to the edge.
// You should enable this if you want to avoid that delay. Enabling it should not have any effect on default iOS gestures.
#define DISABLE_TOUCH_DELAYS 1

// we keep old bools around to support "old" code that might have used them
bool _ios81orNewer = false, _ios82orNewer = false, _ios83orNewer = false, _ios90orNewer = false, _ios91orNewer = false;
bool _ios100orNewer = false, _ios101orNewer = false, _ios102orNewer = false, _ios103orNewer = false;
bool _ios110orNewer = false, _ios111orNewer = false, _ios112orNewer = false;

// was unity rendering already inited: we should not touch rendering while this is false
bool    _renderingInited        = false;
// was unity inited: we should not touch unity api while this is false
bool    _unityAppReady          = false;
// see if there's a need to do internal player pause/resume handling
//
// Typically the trampoline code should manage this internally, but
// there are use cases, videoplayer, plugin code, etc where the player
// is paused before the internal handling comes relevant. Avoid
// overriding externally managed player pause/resume handling by
// caching the state
bool    _wasPausedExternal      = false;
// should we skip present on next draw: used in corner cases (like rotation) to fill both draw-buffers with some content
bool    _skipPresent            = false;
// was app "resigned active": some operations do not make sense while app is in background
bool    _didResignActive        = false;

// was startUnity scheduled: used to make startup robust in case of locking device
static bool _startUnityScheduled    = false;

bool    _supportsMSAA           = false;

#if UNITY_SUPPORT_ROTATION
// Required to enable specific orientation for some presentation controllers: see supportedInterfaceOrientationsForWindow below for details
NSInteger _forceInterfaceOrientationMask = 0;
#endif



@implementation UnityAppController

@synthesize unityView               = _unityView;
@synthesize unityDisplayLink        = _displayLink;

@synthesize rootView                = _rootView;
@synthesize rootViewController      = _rootController;
@synthesize mainDisplay             = _mainDisplay;
@synthesize renderDelegate          = _renderDelegate;
@synthesize quitHandler             = _quitHandler;


#if UNITY_SUPPORT_ROTATION
@synthesize interfaceOrientation    = _curOrientation;
#endif

#pragma mark - Action Handle

- (void)configLocationManager
{
    self.locationManager = [[AMapLocationManager alloc] init];
    
    [self.locationManager setDelegate:self];
    
    //設定期望定位精度
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
    
    //設定不允許系統暫停定位
    [self.locationManager setPausesLocationUpdatesAutomatically:NO];
    
    //設定允許在背景定位
    [self.locationManager setAllowsBackgroundLocationUpdates:YES];
    
    //設定定位逾時時間
    [self.locationManager setLocationTimeout:DefaultLocationTimeout];
    
    //設定逆地理逾時時間
    [self.locationManager setReGeocodeTimeout:DefaultReGeocodeTimeout];
}

- (void)cleanUpAction
{
    //停止定位
    [self.locationManager stopUpdatingLocation];
    
//    [self.locationManager setDelegate:nil];
    
}

- (void)reGeocodeAction
{
    //進行單次帶逆地理定位請求
    [self.locationManager requestLocationWithReGeocode:YES completionBlock:self.completionBlock];
    
}

- (void)locAction
{
    //進行單次定位請求
    [self.locationManager requestLocationWithReGeocode:NO completionBlock:self.completionBlock];
}

- (void)initCompleteBlock
{
    self.completionBlock = ^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error)
    {
        NSString* errMsg = @"";
        int errCode = 0;
        if (error != nil && error.code == AMapLocationErrorLocateFailed)
        {
            errCode = 2;
            errMsg = @"定位錯誤";
            //定位錯誤:此時location和regeocode沒有傳回值,不進行annotation的添加
            NSLog(@"定位錯誤:{%ld - %@};", (long)error.code, error.localizedDescription);
            return;
        }
        else if (error != nil
                 && (error.code == AMapLocationErrorReGeocodeFailed
                     || error.code == AMapLocationErrorTimeOut
                     || error.code == AMapLocationErrorCannotFindHost
                     || error.code == AMapLocationErrorBadURL
                     || error.code == AMapLocationErrorNotConnectedToInternet
                     || error.code == AMapLocationErrorCannotConnectToHost))
        {
            errCode = 2;
            errMsg = @"定位失敗";
            //逆地理錯誤:在帶逆地理的單次定位中,逆地理過程可能發生錯誤,此時location有傳回值,regeocode無傳回值,進行annotation的添加
            NSLog(@"逆地理錯誤:{%ld - %@};", (long)error.code, error.localizedDescription);
        }
        else if (error != nil && error.code == AMapLocationErrorRiskOfFakeLocation)
        {
            errCode = 2;
            errMsg = @"定位錯誤,存在虛拟定位的風險";
            //存在虛拟定位的風險:此時location和regeocode沒有傳回值,不進行annotation的添加
            NSLog(@"存在虛拟定位的風險:{%ld - %@};", (long)error.code, error.localizedDescription);
            return;
        }
        else
        {
            errCode = 0;
            //沒有錯誤:location有傳回值,regeocode是否有傳回值取決于是否進行逆地理操作,進行annotation的添加
        }
        //修改label顯示内容
        NSString* log = @"";
        if (regeocode)
        {
            log = [NSString stringWithFormat:@"%@ \n %@-%@-%.2fm-%.2f-%.2f", regeocode.formattedAddress,regeocode.citycode, regeocode.adcode, location.horizontalAccuracy,location.coordinate.latitude,location.coordinate.longitude];
        }
        else
        {
            log = [NSString stringWithFormat:@"lat:%f;lon:%f \n accuracy:%.2fm", location.coordinate.latitude, location.coordinate.longitude, location.horizontalAccuracy];
        }
        NSLog(@"定位結果:%@",log);
        
        // 轉json發送給unity
        if(regeocode)
        {
            NSDictionary *msgJson = @{@"jingdu" : [NSString stringWithFormat:@"%0.2f",location.coordinate.longitude],
                                      @"weidu" : [NSString stringWithFormat:@"%0.2f",location.coordinate.latitude],
                                      @"adress" : regeocode.formattedAddress,
                                      @"code" : [NSNumber numberWithInt:errCode],
                                      @"msg" : errMsg
                                      };
//            BOOL isYes = [NSJSONSerialization isValidJSONObject:msgJson];
            NSData *msgJsonData = [NSJSONSerialization dataWithJSONObject:msgJson options:0 error:NULL];
            
            NSString* name = @"ThirdpartyManager";
            NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
            [dictionary setValue:@1 forKey:@"Platformtype"];
            [dictionary setValue:@9 forKey:@"code"];
            [dictionary setValue:[[NSString alloc] initWithData:msgJsonData encoding:NSUTF8StringEncoding] forKey:@"msg"];
            //轉成JSON
            NSError *error = nil;
            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
                                                               options:NSJSONWritingPrettyPrinted
                                                                 error:&error];
            if (error)
            {
                NSLog(@"dic->%@",error);
            }
            
            NSString * jsonString  =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
            UnitySendMessage([name cStringUsingEncoding:NSUTF8StringEncoding],
                             "ThridToUnity",
                             [jsonString cStringUsingEncoding:NSUTF8StringEncoding]);
            NSLog(@"code:%@",jsonString);
        }else{
//            self.reGeocodeAction();
            [self reGeocodeAction];
        }
    };
 
}

- (void)requestMirc
{
    [[SystemPermissionsManager sharedManager] requestAuthorization:KAVAudioSession];
}

- (void)openBrower:(NSNotification *)notification
{
    NSString* strHtml = [notification.userInfo objectForKey:@"text"];
    // 1.建立webview,并設定大小,"20"為狀态欄高度
//    WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 20, self.rootView.frame.size.width, self.rootView.frame.size.height - 20)];
    //配置環境
//    WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];
//    WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.rootView.frame.size.width, self.rootView.frame.size.height) configuration:config];
//    webView.navigationDelegate = self;
//    webView.UIDelegate = self;
//    // 加載網頁
//    [webView loadHTMLString:strHtml baseURL:nil];
//    [config.userContentController addScriptMessageHandler:self name:@"closeWindow"];
//
//    // 最後将webView添加到界面
//    [self.rootView addSubview:webView];
    
    BrowserViewController *browController = [[BrowserViewController alloc]init];
    browController.strHtml = strHtml;
    GetAppController().window.rootViewController = browController;
}


//


- (id)init
{
    if ((self = _UnityAppController = [super init]))
    {
        // due to clang issues with generating warning for overriding deprecated methods
        // we will simply assert if deprecated methods are present
        // NB: methods table is initied at load (before this call), so it is ok to check for override
        NSAssert(![self respondsToSelector: @selector(createUnityViewImpl)],
            @"createUnityViewImpl is deprecated and will not be called. Override createUnityView"
        );
        NSAssert(![self respondsToSelector: @selector(createViewHierarchyImpl)],
            @"createViewHierarchyImpl is deprecated and will not be called. Override willStartWithViewController"
        );
        NSAssert(![self respondsToSelector: @selector(createViewHierarchy)],
            @"createViewHierarchy is deprecated and will not be implemented. Use createUI"
        );
    }
    return self;
}

- (void)setWindow:(id)object        {}
- (UIWindow*)window                 { return _window; }


- (void)shouldAttachRenderDelegate  {}
- (void)preStartUnity               {}


- (void)startUnity:(UIApplication*)application
{
    NSAssert(_unityAppReady == NO, @"[UnityAppController startUnity:] called after Unity has been initialized");

    UnityInitApplicationGraphics();

    // we make sure that first level gets correct display list and orientation
    [[DisplayManager Instance] updateDisplayListCacheInUnity];

    UnityLoadApplication();
    Profiler_InitProfiler();

    [self showGameUI];
    [self createDisplayLink];

    UnitySetPlayerFocus(1);
}

extern "C" void UnityDestroyDisplayLink()
{
    [GetAppController() destroyDisplayLink];
}

extern "C" void UnityRequestQuit()
{
    _didResignActive = true;
    if (GetAppController().quitHandler)
        GetAppController().quitHandler();
    else
        exit(0);
}

#if UNITY_SUPPORT_ROTATION

- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
{
    // No rootViewController is set because we are switching from one view controller to another, all orientations should be enabled
    if ([window rootViewController] == nil)
        return UIInterfaceOrientationMaskAll;

    // Some presentation controllers (e.g. UIImagePickerController) require portrait orientation and will throw exception if it is not supported.
    // At the same time enabling all orientations by returning UIInterfaceOrientationMaskAll might cause unwanted orientation change
    // (e.g. when using UIActivityViewController to "share to" another application, iOS will use supportedInterfaceOrientations to possibly reorient).
    // So to avoid exception we are returning combination of constraints for root view controller and orientation requested by iOS.
    // _forceInterfaceOrientationMask is updated in willChangeStatusBarOrientation, which is called if some presentation controller insists on orientation change.
    return [[window rootViewController] supportedInterfaceOrientations] | _forceInterfaceOrientationMask;
}

- (void)application:(UIApplication*)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration
{
    // Setting orientation mask which is requested by iOS: see supportedInterfaceOrientationsForWindow above for details
    _forceInterfaceOrientationMask = 1 << newStatusBarOrientation;
}

#endif

#if !PLATFORM_TVOS
- (void)application:(UIApplication*)application didReceiveLocalNotification:(UILocalNotification*)notification
{
    AppController_SendNotificationWithArg(kUnityDidReceiveLocalNotification, notification);
    UnitySendLocalNotification(notification);
}

#endif

#if UNITY_USES_REMOTE_NOTIFICATIONS
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
    AppController_SendNotificationWithArg(kUnityDidReceiveRemoteNotification, userInfo);
    UnitySendRemoteNotification(userInfo);
}

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    AppController_SendNotificationWithArg(kUnityDidRegisterForRemoteNotificationsWithDeviceToken, deviceToken);
    UnitySendDeviceToken(deviceToken);
}

#if !PLATFORM_TVOS
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
    AppController_SendNotificationWithArg(kUnityDidReceiveRemoteNotification, userInfo);
    UnitySendRemoteNotification(userInfo);
    if (handler)
    {
        handler(UIBackgroundFetchResultNoData);
    }
}

#endif

- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
    AppController_SendNotificationWithArg(kUnityDidFailToRegisterForRemoteNotificationsWithError, error);
    UnitySendRemoteNotificationError(error);
    // alas people do not check remote notification error through api (which is clunky, i agree) so log here to have at least some visibility
    ::printf("\nFailed to register for remote notifications:\n%s\n\n", [[error localizedDescription] UTF8String]);
}

#endif

// UIApplicationOpenURLOptionsKey was added only in ios10 sdk, while we still support ios9 sdk
- (BOOL)application:(UIApplication*)app openURL:(NSURL*)url options:(NSDictionary<NSString*, id>*)options
{
    id sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey], annotation = options[UIApplicationOpenURLOptionsAnnotationKey];

    NSMutableDictionary<NSString*, id>* notifData = [NSMutableDictionary dictionaryWithCapacity: 3];
    if (url) notifData[@"url"] = url;
    if (sourceApplication) notifData[@"sourceApplication"] = sourceApplication;
    if (annotation) notifData[@"annotation"] = annotation;

    AppController_SendNotificationWithArg(kUnityOnOpenURL, notifData);

    NSString *query = url.query;
    if ([url.scheme isEqualToString:@"ylscqp"]) {
        NSArray *array = [query componentsSeparatedByString:@"="]; //從字元A中分隔成2個元素的數組
        if ( [array count] > 0 && [array containsObject:@"roomNum"] ){
            NSLog(@"query1 : %@ - %@ - %@ ",query,array[0],array[1]);
            NSString* name = @"ThirdpartyManager";
            NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
            [dictionary setValue:@1 forKey:@"Platformtype"];
            [dictionary setValue:@100 forKey:@"code"];
            [dictionary setValue:array[1] forKey:@"msg"];
            
            //轉成JSON
            NSError *error = nil;
            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
                                                               options:NSJSONWritingPrettyPrinted
                                                                 error:&error];
            if (error)
            {
                NSLog(@"dic->%@",error);
            }
            
            NSString * jsonString  =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
            
            NSLog(@"jsonString1->%@",jsonString);
            UnitySendMessage([name cStringUsingEncoding:NSUTF8StringEncoding],
                             "ThridToUnity",
                             [jsonString cStringUsingEncoding:NSUTF8StringEncoding]);
        }
        
    }
    
    return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    if ([url.scheme isEqualToString:@"ylscqp"]) {
        NSMutableDictionary *parm = [[NSMutableDictionary alloc]init];
        
        //傳入url建立url元件類
        NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:url.absoluteString];
        
        //回調周遊所有參數,添加入字典
        [urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [parm setObject:obj.value forKey:obj.name];
        }];
        
        NSString* roomNum = [parm valueForKey:@"roomNum"];
        NSString* name = @"ThirdpartyManager";
        NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
        [dictionary setValue:@1 forKey:@"Platformtype"];
        [dictionary setValue:@100 forKey:@"code"];
        [dictionary setValue:roomNum forKey:@"msg"];
        
        //轉成JSON
        NSError *error = nil;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
                                                           options:NSJSONWritingPrettyPrinted
                                                             error:&error];
        if (error)
        {
            NSLog(@"dic->%@",error);
        }
        
        NSString * jsonString  =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        NSLog(@"jsonString3->%@",jsonString);
        
        UnitySendMessage([name cStringUsingEncoding:NSUTF8StringEncoding],
                         "ThridToUnity",
                         [jsonString cStringUsingEncoding:NSUTF8StringEncoding]);

    }
    
    return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}


-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
    
//    NSLog(@"userActivity : %@",userActivity.webpageURL.description);
//    NSLog(@"continueUserActiity enter");
//    NSLog(@"\tAction Type : %@", userActivity.activityType);
//    NSLog(@"\tURL         : %@", userActivity.webpageURL);
//    NSLog(@"\tuserinfo :%@",userActivity.userInfo);
    NSURL* url = userActivity.webpageURL;
    
    
    NSMutableDictionary *parm = [[NSMutableDictionary alloc]init];
    
    //傳入url建立url元件類
    NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:url.absoluteString];
    
    //回調周遊所有參數,添加入字典
    [urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [parm setObject:obj.value forKey:obj.name];
    }];
    
    NSString* roomNum = [parm valueForKey:@"roomNum"];
    NSString* name = @"ThirdpartyManager";
    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
    [dictionary setValue:@1 forKey:@"Platformtype"];
    [dictionary setValue:@100 forKey:@"code"];
    [dictionary setValue:roomNum forKey:@"msg"];

    //轉成JSON
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
                                                       options:NSJSONWritingPrettyPrinted
                                                         error:&error];
    if (error)
    {
        NSLog(@"dic->%@",error);
    }

    NSString * jsonString  =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    NSLog(@"jsonString3->%@",jsonString);

    UnitySendMessage([name cStringUsingEncoding:NSUTF8StringEncoding],
                     "ThridToUnity",
                     [jsonString cStringUsingEncoding:NSUTF8StringEncoding]);
    

    return YES;
}



- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    return  [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}


- (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    AppController_SendNotificationWithArg(kUnityWillFinishLaunchingWithOptions, launchOptions);
    return YES;
}

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    ::printf("-> applicationDidFinishLaunching()\n");

    // send notfications
#if !PLATFORM_TVOS
    if (UILocalNotification* notification = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey])
        UnitySendLocalNotification(notification);

    if ([UIDevice currentDevice].generatesDeviceOrientationNotifications == NO)
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
#endif

    UnityInitApplicationNoGraphics([[[NSBundle mainBundle] bundlePath] UTF8String]);

    [self selectRenderingAPI];
    [UnityRenderingView InitializeForAPI: self.renderingAPI];

    _window         = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
    _unityView      = [self createUnityView];

    [DisplayManager Initialize];
    _mainDisplay    = [DisplayManager Instance].mainDisplay;
    [_mainDisplay createWithWindow: _window andView: _unityView];

    [self createUI];
    [self preStartUnity];

    // if you wont use keyboard you may comment it out at save some memory
    [KeyboardDelegate Initialize];

#if !PLATFORM_TVOS && DISABLE_TOUCH_DELAYS
    for (UIGestureRecognizer *g in _window.gestureRecognizers)
    {
        g.delaysTouchesBegan = false;
    }
#endif
    
    [WXApi startLogByLevel:WXLogLevelNormal logBlock:^(NSString *log) {
        NSLog(@"log : %@", log);
    }];
    
    
    // 高德地圖
     [AMapServices sharedServices].apiKey [email protected]"dsadasdasda53534543543";// release

    [self initCompleteBlock];
    [self configLocationManager];
    //增加一個通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reGeocodeAction) name:@"OpenLocaltion" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cleanUpAction) name:@"StopLocaltion" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(requestMirc) name:@"RequestMirc" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(openBrower:) name:@"OpenBrower" object:nil];

  
    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication*)application
{
    ::printf("-> applicationDidEnterBackground()\n");
}

- (void)applicationWillEnterForeground:(UIApplication*)application
{
    ::printf("-> applicationWillEnterForeground()\n");

    // applicationWillEnterForeground: might sometimes arrive *before* actually initing unity (e.g. locking on startup)
    if (_unityAppReady)
    {
        // if we were showing video before going to background - the view size may be changed while we are in background
        [GetAppController().unityView recreateRenderingSurfaceIfNeeded];
    }
}

- (void)applicationDidBecomeActive:(UIApplication*)application
{
    ::printf("-> applicationDidBecomeActive()\n");

    [self removeSnapshotView];

    if (_unityAppReady)
    {
        if (UnityIsPaused() && _wasPausedExternal == false)
        {
            UnityWillResume();
            UnityPause(0);
        }
        if (_wasPausedExternal)
        {
            if (UnityIsFullScreenPlaying())
                TryResumeFullScreenVideo();
        }
        UnitySetPlayerFocus(1);
    }
    else if (!_startUnityScheduled)
    {
        _startUnityScheduled = true;
        [self performSelector: @selector(startUnity:) withObject: application afterDelay: 0];
    }

    _didResignActive = false;
}

- (void)removeSnapshotView
{
    // do this on the main queue async so that if we try to create one
    // and remove in the same frame, this always happens after in the same queue
    dispatch_async(dispatch_get_main_queue(), ^{
        if (_snapshotView)
        {
            [_snapshotView removeFromSuperview];
            _snapshotView = nil;
        }
    });
}

- (void)applicationWillResignActive:(UIApplication*)application
{
    ::printf("-> applicationWillResignActive()\n");

    if (_unityAppReady)
    {
        UnitySetPlayerFocus(0);

        _wasPausedExternal = UnityIsPaused();
        if (_wasPausedExternal == false)
        {
            // do pause unity only if we dont need special background processing
            // otherwise batched player loop can be called to run user scripts
            int bgBehavior = UnityGetAppBackgroundBehavior();
            if (bgBehavior == appbgSuspend || bgBehavior == appbgExit)
            {
                // Force player to do one more frame, so scripts get a chance to render custom screen for minimized app in task manager.
                // NB: UnityWillPause will schedule OnApplicationPause message, which will be sent normally inside repaint (unity player loop)
                // NB: We will actually pause after the loop (when calling UnityPause).
                UnityWillPause();
                [self repaint];
                UnityPause(1);

                // this is done on the next frame so that
                // in the case where unity is paused while going
                // into the background and an input is deactivated
                // we don't mess with the view hierarchy while taking
                // a view snapshot (case 760747).
                dispatch_async(dispatch_get_main_queue(), ^{
                    // if we are active again, we don't need to do this anymore
                    if (!_didResignActive)
                    {
                        return;
                    }

                    _snapshotView = [self createSnapshotView];
                    if (_snapshotView)
                        [_rootView addSubview: _snapshotView];
                });
            }
        }
    }

    _didResignActive = true;
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication*)application
{
    ::printf("WARNING -> applicationDidReceiveMemoryWarning()\n");
    UnityLowMemory();
}

- (void)applicationWillTerminate:(UIApplication*)application
{
    ::printf("-> applicationWillTerminate()\n");

    Profiler_UninitProfiler();
    UnityCleanup();

    extern void SensorsCleanup();
    SensorsCleanup();
}

- (void)application:(UIApplication*)application handleEventsForBackgroundURLSession:(nonnull NSString *)identifier completionHandler:(nonnull void (^)())completionHandler
{
    NSDictionary* arg = @{identifier: completionHandler};
    AppController_SendNotificationWithArg(kUnityHandleEventsForBackgroundURLSession, arg);
}

@end


void AppController_SendNotification(NSString* name)
{
    [[NSNotificationCenter defaultCenter] postNotificationName: name object: GetAppController()];
}

void AppController_SendNotificationWithArg(NSString* name, id arg)
{
    [[NSNotificationCenter defaultCenter] postNotificationName: name object: GetAppController() userInfo: arg];
}

void AppController_SendUnityViewControllerNotification(NSString* name)
{
    [[NSNotificationCenter defaultCenter] postNotificationName: name object: UnityGetGLViewController()];
}

extern "C" UIWindow*            UnityGetMainWindow()
{
    return GetAppController().mainDisplay.window;
}

extern "C" UIViewController*    UnityGetGLViewController()
{
    return GetAppController().rootViewController;
}

extern "C" UIView*              UnityGetGLView()
{
    return GetAppController().unityView;
}

extern "C" ScreenOrientation    UnityCurrentOrientation()   { return GetAppController().unityView.contentOrientation; }


bool LogToNSLogHandler(LogType logType, const char* log, va_list list)
{
    NSLogv([NSString stringWithUTF8String: log], list);
    return true;
}

static void AddNewAPIImplIfNeeded();

// From https://stackoverflow.com/questions/4744826/detecting-if-ios-app-is-run-in-debugger
static bool isDebuggerAttachedToConsole(void)
// Returns true if the current process is being debugged (either
// running under the debugger or has a debugger attached post facto).
{
    int                 junk;
    int                 mib[4];
    struct kinfo_proc   info;
    size_t              size;

    // Initialize the flags so that, if sysctl fails for some bizarre
    // reason, we get a predictable result.

    info.kp_proc.p_flag = 0;

    // Initialize mib, which tells sysctl the info we want, in this case
    // we're looking for information about a specific process ID.

    mib[0] = CTL_KERN;
    mib[1] = KERN_PROC;
    mib[2] = KERN_PROC_PID;
    mib[3] = getpid();

    // Call sysctl.

    size = sizeof(info);
    junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
    assert(junk == 0);

    // We're being debugged if the P_TRACED flag is set.

    return ((info.kp_proc.p_flag & P_TRACED) != 0);
}

void UnityInitTrampoline()
{
    InitCrashHandling();

    NSString* version = [[UIDevice currentDevice] systemVersion];
#define CHECK_VER(s) [version compare: s options: NSNumericSearch] != NSOrderedAscending
    _ios81orNewer  = CHECK_VER(@"8.1"),  _ios82orNewer  = CHECK_VER(@"8.2"),  _ios83orNewer  = CHECK_VER(@"8.3");
    _ios90orNewer  = CHECK_VER(@"9.0"),  _ios91orNewer  = CHECK_VER(@"9.1");
    _ios100orNewer = CHECK_VER(@"10.0"), _ios101orNewer = CHECK_VER(@"10.1"), _ios102orNewer = CHECK_VER(@"10.2"), _ios103orNewer = CHECK_VER(@"10.3");
    _ios110orNewer = CHECK_VER(@"11.0"), _ios111orNewer = CHECK_VER(@"11.1"), _ios112orNewer = CHECK_VER(@"11.2");

#undef CHECK_VER

    AddNewAPIImplIfNeeded();

#if !TARGET_IPHONE_SIMULATOR
    // Use NSLog logging if a debugger is not attached, otherwise we write to stdout.
    if (!isDebuggerAttachedToConsole())
        UnitySetLogEntryHandler(LogToNSLogHandler);
#endif
}

extern "C" bool UnityiOS81orNewer() { return _ios81orNewer; }
extern "C" bool UnityiOS82orNewer() { return _ios82orNewer; }
extern "C" bool UnityiOS90orNewer() { return _ios90orNewer; }
extern "C" bool UnityiOS91orNewer() { return _ios91orNewer; }
extern "C" bool UnityiOS100orNewer() { return _ios100orNewer; }
extern "C" bool UnityiOS101orNewer() { return _ios101orNewer; }
extern "C" bool UnityiOS102orNewer() { return _ios102orNewer; }
extern "C" bool UnityiOS103orNewer() { return _ios103orNewer; }
extern "C" bool UnityiOS110orNewer() { return _ios110orNewer; }
extern "C" bool UnityiOS111orNewer() { return _ios111orNewer; }
extern "C" bool UnityiOS112orNewer() { return _ios112orNewer; }

// sometimes apple adds new api with obvious fallback on older ios.
// in that case we simply add these functions ourselves to simplify code
static void AddNewAPIImplIfNeeded()
{
    if (![[CADisplayLink class] instancesRespondToSelector: @selector(setPreferredFramesPerSecond:)])
    {
        IMP CADisplayLink_setPreferredFramesPerSecond_IMP = imp_implementationWithBlock(^void(id _self, NSInteger fps) {
            typedef void (*SetFrameIntervalFunc)(id, SEL, NSInteger);
            UNITY_OBJC_CALL_ON_SELF(_self, @selector(setFrameInterval:), SetFrameIntervalFunc, (int)(60.0f / fps));
        });
        class_replaceMethod([CADisplayLink class], @selector(setPreferredFramesPerSecond:), CADisplayLink_setPreferredFramesPerSecond_IMP, CADisplayLink_setPreferredFramesPerSecond_Enc);
    }

    if (![[UIScreen class] instancesRespondToSelector: @selector(maximumFramesPerSecond)])
    {
        IMP UIScreen_MaximumFramesPerSecond_IMP = imp_implementationWithBlock(^NSInteger(id _self) {
            return 60;
        });
        class_replaceMethod([UIScreen class], @selector(maximumFramesPerSecond), UIScreen_MaximumFramesPerSecond_IMP, UIScreen_maximumFramesPerSecond_Enc);
    }

    if (![[UIView class] instancesRespondToSelector: @selector(safeAreaInsets)])
    {
        IMP UIView_SafeAreaInsets_IMP = imp_implementationWithBlock(^UIEdgeInsets(id _self) {
            return UIEdgeInsetsZero;
        });
        class_replaceMethod([UIView class], @selector(safeAreaInsets), UIView_SafeAreaInsets_IMP, UIView_safeAreaInsets_Enc);
    }
}

           

使用方法,在Unity到處的接口裡面直接 調用就可以

// 開啟定位
[[NSNotificationCenter defaultCenter] postNotificationName:@"OpenLocaltion"  object:nil];

// 停止定位
[[NSNotificationCenter defaultCenter] postNotificationName:@"StopLocaltion"  object:nil];
           

繼續閱讀