iOS小技能:应用外导航

简介: 术语:1. 应用外导航:是指以URL跳转的方式(在iOS中就是以URL Scheme的方式),直接跳到对应的地图APP中,直接利用对方的功能来导航。这样的优点,一是接入方便,二是不增加自己APP的开销。2. 应用内导航:是指使用地图服务提供的SDK(如高德,百度),直接将导航功能嵌入到我们自己的APP内部。需求:跳转到已经安装的地图背景:为了减少app内存开支,以URI跳转的方式直接跳转到对应的地图进行导航,让最专业的人做最专业的事。

前言

术语:

  1. 应用外导航:是指以URL跳转的方式(在iOS中就是以URL Scheme的方式),直接跳到对应的地图APP中,直接利用对方的功能来导航。这样的优点,一是接入方便,二是不增加自己APP的开销。
  2. 应用内导航:是指使用地图服务提供的SDK(如高德,百度),直接将导航功能嵌入到我们自己的APP内部。

需求:跳转到已经安装的地图
背景:为了减少app内存开支,以URI跳转的方式直接跳转到对应的地图进行导航,让最专业的人做最专业的事。

I 开发步骤

1.1 添加Scheme白名单

iOS 9 之后涉及到app跳转时,系统会自动到项目info.plist下检测是否设置相关平台Scheme。

<!--具体方法:在项目的info.plist中添加LSApplicationQueriesSchemes字段,类型是Array,然后添加Item。-->
    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>baidumap</string>
        <string>iosamap</string>
        <string>comgooglemaps</string>
        <string>qqmap</string>
    </array>
苹果自带地图: if ( [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"http://maps.apple.com/"]]) {

百度地图 :baidumap://

高德地图 :iosamap://

谷歌地图: comgooglemaps://

腾讯地图:qqmap://

1.2 检测是否安装相应APP

使用canOpenURL:方法来检测该手机是否安装相应APP

- (void)showSheet
{
    NSString * appleMap  = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"http://maps.apple.com/"]] ? @"苹果地图" : nil;
    
    NSString * baiduMap  = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]] ? @"百度地图" : nil;
    NSString * gaodeMap  = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]] ? @"高德地图":nil;
    //谷歌地图:不能用,需翻_墙
    NSString * googleMap = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://"]] ? nil :nil;
    //
    NSString * tencentMap  = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://map/"]] ? nil : nil;
    
    
    UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:@"请选择您已经安装的导航工具" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:gaodeMap otherButtonTitles:appleMap,baiduMap,tencentMap,nil];//googleMap
    [actionSheet showInView:[UIApplication sharedApplication].keyWindow];
}

1.3 封装跳转URL

  1. 地址系列
    //    //腾讯,type=bus 或 type=drive 或 type=walk 或 type=bike referer开发者key:
    NSString * tencentAddressUrl = [[NSString stringWithFormat:@"qqmap://map/routeplan?type=walk&from=%@&to=%@&policy=1&referer=%@",mb.start, mb.end,_appName] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    //苹果
    NSString *appleAddressUrl = [[NSString stringWithFormat:@"http://maps.apple.com/?saddr=%@&daddr=%@&dirflg=w",_start, mb.end] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    //百度
    NSString *baiduAddressUrl = [[NSString stringWithFormat:@"baidumap://map/direction?origin=%@&destination=%@&mode=walking&region=%@&src=%@",mb.start, mb.end,_city,_appName] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    //高德
    NSString *gaodeAddressUrl = [[NSString stringWithFormat:@"iosamap://path?sourceApplication=%@&sid=BGVIS1&sname=%@&did=BGVIS2&dname=%@&dev=0&m=2&t=2",_appName,mb.start,mb.end] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    //谷歌
    NSString *googleAddressUrl = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=%@&daddr=%@&directionsmode=bicycling",_appName,_urlScheme,mb.start, mb.end] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
  1. 通过经纬度参数打开
    NSString * baiduUrlStr = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=目的地&mode=driving&coord_type=gcj02",mb.Coordinate2D.latitude, mb.Coordinate2D.longitude] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    NSString * goooleUrlStr = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",_appName,_urlScheme,mb.Coordinate2D.latitude, mb.Coordinate2D.longitude] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    NSString * gaodeUrlStr= [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",_appName,_urlScheme,mb.Coordinate2D.latitude, mb.Coordinate2D.longitude] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
  1. 方便弹回来
为了能够跳转回的自己的APP,需要在 URL Types里填写你的app的 URL Schemes

II 代码封装

完整代码获取,请联系我:#公号:iOS逆向

2.1 API

#import <MapKit/MKMapItem.h>//用于苹果自带地图

#import <MapKit/MKTypes.h>//用于苹果自带地图

/**
 地图类型
 */
typedef enum : NSUInteger {
    k_MapSelect4Apple = 0,
    k_MapSelect4Baidu,
    k_MapSelect4Google,
    k_MapSelect4Gaode,
    k_MapSelect4Tencent
} k_MapSelect;

/**
 跳转URL的参数类型
 */
typedef enum : NSUInteger {
    /**
     地址
     */
    k_MapNavStyle4Address = 0,
    /**
     经纬度
     */
    k_MapNavStyle4Coordinates
} k_MapNavStyle;


@interface MapNavigationManager : NSObject

+ (void)showSheetWithCity:(NSString *)city start:(NSString *)start end:(NSString *)end;
+ (void)showSheetWithCoordinate2D:(CLLocationCoordinate2D)Coordinate2D;

@end

用法

            NSString *start = @"";            
            [ERPMapNavManager showSheetWithCity:self.models.delivery.cityName start:start end:self.models.delivery.address];
            

2.2 核心实现

    NSString * urlString = [self getUrlStr:index];
    if (urlString != nil) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
    }

2.3 注意事项

  1. 腾讯地图需要给默认开始位置:https://lbs.qq.com/webApi/uriV1/uriGuide/uriMobileGuide
    NSString *start = mb.start.length>0 ?mb.start :@"我的位置";
  1. 创建UIActionSheet时,otherButtonTitles参数最多支持3个,因为推荐使用UIAlertController
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请选择您已经安装的导航工具" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    __weak __typeof__(self) weakSelf = self;

    
    if(gaodeMap){
        UIAlertAction *action = [UIAlertAction actionWithTitle:gaodeMap style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            
            
            NSString * urlString = [self getUrlStr:k_MapSelect4Gaode];
            
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

        }];

        [alert addAction:action];
    }
    
    if(appleMap){
        UIAlertAction *action = [UIAlertAction actionWithTitle:appleMap style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            
            if(weakSelf.style == k_MapNavStyle4Coordinates)
                
            {
                MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
                MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:self.Coordinate2D addressDictionary:nil]];
                [MKMapItem openMapsWithItems:@[currentLocation, toLocation]
                               launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];
                return;
            }
            
            NSString * urlString = [self getUrlStr:k_MapSelect4Apple];
            
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

        }];

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

    [[QCT_Common getCurrentVC] presentViewController:alert animated:YES completion:^{
        
    }];
    

see also

用代码修改图片颜色:https://blog.csdn.net/z929118967/article/details/104353863

        UIImage *icon_right = [UIImage imageNamed:@"icon_right"];
        
        icon_right = [icon_right imageWithRenderingMode:(UIImageRenderingModeAlwaysTemplate)];
        
        tmp.image =icon_right;
        
        tmp.tintColor = UIColor.whiteColor;
        

百度地图App:[http://developer.baidu.com/map/wiki/index.php?title=uri/api/ios
](http://developer.baidu.com/map/wiki/index.php?title=uri/api/ios
)

百度地图:[http://lbsyun.baidu.com/index.php?title=uri/api/ios
](http://lbsyun.baidu.com/index.php?title=uri/api/ios
)

苹果地图:[https://developer.apple.com/reference/mapkit/mkmapitem
](https://developer.apple.com/reference/mapkit/mkmapitem
)

腾讯地图:[http://lbs.qq.com/uri_v1/guide-route.html
](http://lbs.qq.com/uri_v1/guide-route.html
)

目录
相关文章
|
2月前
|
搜索推荐 API 开发工具
打造个性化天气应用:从零开始的iOS开发之旅
【8月更文挑战第31天】本文是一篇针对初学者的iOS应用开发指南,将引导读者通过Swift和iOS SDK构建一个简单而美观的天气应用。我们将探索如何利用API获取实时天气数据,并在应用中实现用户友好的界面设计。文章不仅包括代码示例,还提供了设计理念和用户体验优化的建议,旨在帮助初学者理解iOS开发的基础知识,并激发他们创造个性化应用的兴趣。
|
2月前
|
物联网 区块链 vr&ar
未来已来:探索区块链、物联网与虚拟现实技术的融合与应用安卓与iOS开发中的跨平台框架选择
【8月更文挑战第30天】在科技的巨轮下,新技术不断涌现,引领着社会进步。本文将聚焦于当前最前沿的技术——区块链、物联网和虚拟现实,探讨它们各自的发展趋势及其在未来可能的应用场景。我们将从这些技术的基本定义出发,逐步深入到它们的相互作用和集成应用,最后展望它们如何共同塑造一个全新的数字生态系统。
|
9天前
|
存储 IDE 开发工具
移动应用开发之旅:打造你的首个iOS应用
【9月更文挑战第23天】在数字化浪潮中,移动应用已成为连接用户与数字世界的关键桥梁。本文将带领读者踏上开发属于自己的第一个iOS移动应用的旅程,从理解移动操作系统的核心概念出发,逐步深入到实际的应用构建过程中。通过简洁明了的语言和具体的代码示例,我们将一起探索如何在苹果的iOS平台上实现一个简单的“待办事项列表”应用,让读者不仅能够学习到编程知识,还能体会到将想法转化为现实产品的成就感。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供一个实用的指南,帮助你迈出成为移动应用开发者的第一步。
|
23天前
|
开发框架 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的指南
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文将深入浅出地对比这两大操作系统的开发环境、工具和用户体验设计,揭示它们在编程语言、开发工具以及市场定位上的根本差异。我们将从开发者的视角出发,逐步剖析如何根据项目需求和目标受众选择适合的平台,同时探讨跨平台开发框架的利与弊,为那些立志于打造下一个热门应用的开发者提供一份实用的指南。
47 5
|
28天前
|
Swift iOS开发 UED
揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【9月更文挑战第5天】本文通过具体案例介绍如何在iOS应用中使用Swift与UIKit实现自定义按钮动画,当用户点击按钮时,按钮将从圆形变为椭圆形并从蓝色渐变到绿色,释放后恢复原状。文中详细展示了代码实现过程及动画平滑过渡的技巧,帮助读者提升应用的视觉体验与特色。
39 11
|
1月前
|
API iOS开发
探索iOS开发:打造你的第一个天气应用
【8月更文挑战第31天】 在这篇文章中,我们将一起潜入iOS开发的海洋,从初学者的角度出发,一步步构建我们自己的天气应用。通过实际的项目实践,你将学习到如何获取网络数据、如何在界面上展示这些数据,以及如何处理用户交互。文章以通俗易懂的语言,结合代码示例,引导你理解并实现一个简单天气应用的核心功能。无论你是编程新手还是希望扩展你的iOS开发技能,这篇文章都将为你提供宝贵的指导和启发。
|
2月前
|
存储 JSON API
探索iOS开发:打造你的第一个天气应用
【8月更文挑战第31天】在这篇文章中,我们将踏上一段激动人心的旅程,从零开始构建一个iOS天气应用。通过这一过程,我们不仅能够掌握Swift编程语言的核心概念,还能深入理解如何与API进行交互以及如何在App Store上发布我们的杰作。无论你是编程新手还是希望扩展你的技能库,这个项目都将为你提供一个实践的平台。让我们携手进入iOS开发的奇妙世界,一步步实现自己的想法,并最终将它们变为现实。
|
2月前
|
测试技术 虚拟化 iOS开发
iOS自动化测试方案(二):Xcode开发者工具构建WDA应用到iphone
这篇文章是iOS自动化测试方案的第二部分,详细介绍了在Xcode开发者工具中构建WebDriverAgent(WDA)应用到iPhone的全过程,包括环境准备、解决构建过程中可能遇到的错误,以及最终成功安装WDA到设备的方法。
95 0
iOS自动化测试方案(二):Xcode开发者工具构建WDA应用到iphone
|
2月前
|
Swift iOS开发 UED
【绝妙创意】颠覆你的视觉体验!揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【8月更文挑战第13天】本文通过一个具体案例,介绍如何使用Swift与UIKit在iOS应用中创建独特的按钮动画效果。当按钮被按下时,其形状从圆形变化为椭圆形,颜色则从蓝色渐变为绿色;释放后,动画反向恢复原状。利用UIView动画方法及弹簧动画效果,实现了平滑自然的过渡。通过调整参数,开发者可以进一步优化动画体验,增强应用的互动性和视觉吸引力。
40 7
|
25天前
|
开发工具 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的关键考量
在数字时代的浪潮中,安卓和iOS这两大操作系统如同双子星座般耀眼夺目,引领着移动应用的潮流。它们各自拥有独特的魅力和深厚的用户基础,为开发者提供了广阔的舞台。然而,正如每枚硬币都有两面,安卓与iOS在开发过程中也展现出了截然不同的特性。本文将深入剖析这两者在开发环境、编程语言、用户体验设计等方面的显著差异,并探讨如何根据目标受众和项目需求做出明智的选择。无论你是初涉移动应用开发的新手,还是寻求拓展技能边界的资深开发者,这篇文章都将为你提供宝贵的见解和实用的建议,帮助你在安卓与iOS的开发之路上更加从容自信地前行。
下一篇
无影云桌面