zoukankan      html  css  js  c++  java
  • iOS_URI跳转方式多种地图导航的代码实践

    先来看一下我们要达到什么效果,就是当我们点导航的时候,会弹出下面这个选择列表。

    blob.png

    当然,如果没有安装某个地图APP,那么对应的选项是不会出现的。检测APP是否安装,只要调用下面这个方法就可以了

    [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"appurlscheme://"];

    关于APP的URL Scheme相关内容这里就不介绍了,大家可以自行去研究

    那么我们上图提到了4个地图应用,分别是:

    1. 苹果地图

    2. 百度地图

    3. 高德地图

    4. 谷歌地图

    这些也是当前我们用得最多的几种地图了(什么,你们说还有腾讯地图? 可惜腾讯地图暂时还不支持URI的方式打开,所以这里就没列出来,等可以用了我会补上)

    下面来对比一下几种地图:

    地图 URL Scheme 文档 是否可以跳回到APP
    苹果地图   文档
    百度地图 baidumap:// 文档
    高德地图 iosamap:// 文档
    谷歌地图 comgooglemaps:// 文档

    苹果地图是系统自带的(而且苹果地图最好的方式也不是用URI的方式开打),所以无需URL Scheme就可以打开的。

    iOS9 开发可能会出现安装了某地图,但是检查不到已经安装!!!

    这时候就需要在plist文件配置白名单了
    <key>LSApplicationQueriesSchemes</key>
            <array>

              <string>baidumap</string>

              <string>iosamap</string>

              <string>comgooglemaps</string>

            </array>

    其次,当跳到地图APP之后可以跳回是一种很好的体验(参考微信的跳转)。但是遗憾的是,苹果地图和百度地图都不支持跳回。

    接下来我们就回到正题,说一说每种地图的跳转方式。

    假设我们有一个指定的目的坐标coordinate,而我们自己的APP的URL Scheme是urlScheme,名称是appName

    假设我们有一个指定的目的坐标coordinate,而我们自己的APP的URL Scheme是urlScheme,名称是appName

    1
    2
    3
    CLLocationCoordinate2D coordinate;
    NSString *urlScheme;
    NSString *appName;

    苹果地图

    苹果地图可以通过openURL的方式打开。

    详细参数请查看 苹果地图URI API https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html

    1
    2
    NSString *urlString = [[NSString stringWithFormat:@"http://maps.apple.com/?daddr=%f,%f&saddr=slat,slng",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

    但是这种方式,不能以当前位置为起点,所以不符合我们的要求。网上说可以用下面这种方式,但是我没成功

    1
    NSString *urlString = [[NSString stringWithFormat:@"http://maps.apple.com/?daddr=%f,%f&saddr=Current+Location",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    但是苹果提供了另一种方式,使用MKMapItem

    1
    2
    3
    4
    5
    MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
    MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil]];
    [MKMapItem openMapsWithItems:@[currentLocation, toLocation] 
                   launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,
                                   MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];

    效果如下

    blob.png

    百度地图

    详细参数请查看  百度地图开放平台> URI API > 接口说明 > iOS端

    1
    2
    NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=目的地&mode=driving&coord_type=gcj02",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

    要注意几点:

    1. origin={{我的位置}}

    这个是不能被修改的 不然无法把出发位置设置为当前位置

    2. destination=latlng:%f,%f|name=目的地

    name=XXXX name这个字段不能省略 否则导航会失败 而后面的文字则可以随便填

    3. coord_type=gcj02

    coord_type允许的值为bd09ll、gcj02、wgs84 如果你APP的地图SDK用的是百度地图SDK 请填bd09ll 否则 就填gcj02 wgs84你基本是用不上了(关于地图加密这里也不多谈 请自行学习)

    效果如下

    blob.png

    高德地图

    详细参数请查看 高德LBS开放>平台开发 > URI API > iOS

    1
    2
    NSString *urlString = [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

    要注意几点:

    1. sourceApplication=%@&backScheme=%@

    sourceApplication代表你自己APP的名称 会在之后跳回的时候显示出来 所以必须填写 backScheme是你APP的URL Scheme 不填是跳不回来的哟

    2. dev=0

    这里填0就行了,跟上面的gcj02一个意思 1代表wgs84 也用不上

    效果如下:

    blob.png

    退出导航后,会提示是否跳回到APP

    blob.png

    谷歌地图

    详细参数请查看官方接口说明:

    https://developers.google.com/maps/documentation/ios/urlscheme

    1
    2
    NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

    要注意几点

    1. x-source=%@&x-success=%@

    跟高德一样 这里分别代表APP的名称和URL Scheme

    2. saddr=

    这里留空则表示从当前位置触发

    效果如下。在有多条路线的时候,谷歌地图会让你选择其中一条

    blob.png

    选择之后就进入了导航页面。

    blob.png

    腾讯地图

    既然提到了腾讯地图 那么还是说一下 从网上和官方文档可以得知 大概调用的URI如下

    1
    2
    NSString *urlString = [[NSString stringWithFormat:@"qqmap://map/routeplan?type=drive&fromcoord=CurrentLocation&tocoord=%f,%f&coord_type=1&policy=0",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

    但是很遗憾,调用之后出错了,无法导航

    效果如下

    blob.png

    部分实现代码如下:

     __block NSString *urlScheme = self.urlScheme;

        __block NSString *appName = self.appName;

        __block CLLocationCoordinate2D coordinate = self.coordinate;

        

        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"选择地图" message:nil preferredStyle:UIAlertControllerStyleActionSheet];

        

        //这个判断其实是不需要的

        if ( [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"http://maps.apple.com/"]])

        {

            UIAlertAction *action = [UIAlertAction actionWithTitle:@"苹果地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

                

                MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];

                MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil]];

                

            currentLocation.name = @"我的位置";

            toLocation.name = @"目的地位置";

                [MKMapItem openMapsWithItems:@[currentLocation, toLocation]

                               launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];

            }];

            

            [alert addAction:action];

        }

        

        if ( [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]])

        {

            UIAlertAction *action = [UIAlertAction actionWithTitle:@"百度地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

                

                NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=目的地&mode=driving&coord_type=gcj02",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

                

                NSLog(@"%@",urlString);

                

                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

                

            }];

            

            [alert addAction:action];

        }

        

        

        if ( [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]])

        {

            UIAlertAction *action = [UIAlertAction actionWithTitle:@"高德地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

                

                NSString *urlString = [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

                

                NSLog(@"%@",urlString);

                

                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

                

            }];

            

            [alert addAction:action];

        }

        

        if ( [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://"]])

        {

            UIAlertAction *action = [UIAlertAction actionWithTitle:@"谷歌地图" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

                

                NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

                

                NSLog(@"%@",urlString);

                

                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

                

            }];

            

            [alert addAction:action];

        }

        

        UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];

        [alert addAction:action];

        

        [self presentViewController:alert animated:YES completion:^{

            

        }];

    文中的demo可以在这里找到

  • 相关阅读:
    在AE中通过SDE添加图层(转)
    上一视图下一视图功能实现(C#+SuperMap Objects)
    [Python入门及进阶笔记]Python基础内置函数小结
    Javascript小球
    64位centos下安装python的PIL模块
    [Python入门及进阶笔记]Python基础集合小结
    C语言的那些小秘密之【链表(二)】
    巴斯卡三角形
    [Python入门及进阶笔记]Python基础数字处理相关模块
    C语言的那些小秘密之【链表(一)】
  • 原文地址:https://www.cnblogs.com/jyking/p/4939637.html
Copyright © 2011-2022 走看看