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
)

高德地图:[http://lbs.amap.com/api/uri-api/guide/ios-uri-explain/navi/
](http://lbs.amap.com/api/uri-api/guide/ios-uri-explain/navi/
)

苹果地图:[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
)

目录
相关文章
|
1月前
|
算法 计算机视觉 iOS开发
iOS 实时图像处理技术:使用 Core Image 和 Metal 进行高效滤镜应用
【4月更文挑战第8天】 在移动设备上实现高效的图像处理功能是现代应用程序开发中的一个关键需求。苹果的iOS平台提供了Core Image和Metal两大技术,它们为开发者提供了强大的工具来实现复杂的图像处理任务。本文将探讨如何使用Core Image进行基础图像处理,并结合Metal的性能优势,开发出一个自定义的实时图像滤镜。我们将通过创建一个能够动态调整参数并且具有实时反馈效果的滤镜来演示这一过程。
|
1月前
|
算法 计算机视觉 iOS开发
iOS 实时图像处理技术:Core Image 框架的应用
【4月更文挑战第8天】 在移动设备上实现高效的图像处理功能,对于提升用户体验和扩展应用程序能力至关重要。苹果公司的iOS平台提供了强大的Core Image框架,它允许开发者以高效和直观的方式执行复杂的图像处理任务。本文将深入探讨Core Image框架的关键特性,并通过实例演示如何在iOS应用中集成实时图像处理功能,不仅提高性能,同时保持了电池寿命的优化。我们将重点讨论面部识别、滤镜应用和性能优化等关键技术点,为读者提供一份全面的iOS图像处理指南。
|
1月前
|
iOS开发
SwiftUI适配iOS16导航控制器引起的闪退
SwiftUI适配iOS16导航控制器引起的闪退
31 0
|
1月前
|
前端开发 JavaScript 程序员
HBuilderX使用mac打包ios应用提示苹果根证书没有安装
HBuilderX使用mac打包ios应用提示苹果根证书没有安装
24 0
|
1月前
|
安全 Swift iOS开发
【Swift 开发专栏】Swift 与 UIKit:构建 iOS 应用界面
【4月更文挑战第30天】本文探讨了Swift和UIKit在构建iOS应用界面的关键技术和实践方法。Swift的简洁语法、类型安全和高效编程模型,加上与UIKit的紧密集成,使开发者能便捷地创建用户界面。UIKit提供视图、控制器、布局、动画和事件处理等功能,支持灵活的界面设计。实践中,遵循设计原则,合理组织视图层次,运用布局和动画,以及实现响应式设计,能提升界面质量和用户体验。文章通过登录、列表和详情界面的实际案例展示了Swift与UIKit的结合应用。
|
1月前
|
定位技术 开发工具 iOS开发
ios9定位服务的app进入后台三分钟收不到经纬度,应用被挂起问题及解决方案
ios9定位服务的app进入后台三分钟收不到经纬度,应用被挂起问题及解决方案
24 0
|
1月前
|
存储 编解码 JSON
利用SwiftUI构建高效iOS天气应用
【4月更文挑战第21天】 在本文中,我们将深入探讨如何运用SwiftUI框架打造一个响应迅速且用户友好的iOS天气应用程序。我们将重点放在利用SwiftUI的声明式语法简化界面开发,并通过结合Core Location和Networking APIs实现实时天气数据的获取与展示。文章将详细阐述整个开发过程,包括API集成、数据模型设计、用户界面布局以及动态适配不同屏幕尺寸的策略。
|
1月前
|
存储 Swift iOS开发
使用Swift开发一个简单的iOS应用的详细步骤。
使用Swift开发iOS应用的步骤包括:创建Xcode项目,设计界面(Storyboard或代码),定义数据模型,实现业务逻辑,连接界面和逻辑,处理数据存储(如Core Data),添加网络请求(必要时),调试与测试,根据测试结果优化改进,最后提交至App Store或其它平台发布。
60 0
|
1月前
|
存储 安全 Swift
【Swift 开发专栏】使用 Swift 开发一个简单的 iOS 应用
【4月更文挑战第30天】本文介绍了使用 Swift 开发简单 iOS 待办事项应用的步骤。首先,阐述了 iOS 开发的吸引力及 Swift 语言的优势。接着,详细说明了应用的需求和设计,包括添加、查看和删除待办事项的功能。开发步骤包括创建项目、界面搭建、数据存储、功能实现,并提供了相关代码示例。最后,强调了实际开发中需注意的细节和优化,旨在帮助初学者掌握 Swift 和 iOS 开发基础。