打开警报,要求选择应用程序以打开地图

Sam*_*Sam 7 dictionary mapkit ios swift

我有一个集成了地图套件的视图控制器.我需要在打开地图之前拍摄警报,要求从地图的所有类似应用中进行选择以打开它.例如,如果谷歌地图应用程序安装在我的iPhone中,则应该有一个选项,以及默认的mapkit视图.是否有可能实现此功能,从iphone扫描每个类似的应用程序,并返回结果作为打开地图的选项.

Emp*_*ess 28

您可以使用sumesh的答案[1]创建一系列检查以映射已安装的应用程序:

var installedNavigationApps : [String] = ["Apple Maps"] // Apple Maps is always installed
Run Code Online (Sandbox Code Playgroud)

以及您可以想到的每个导航应用程序:

if (UIApplication.sharedApplication().canOpenURL(url: NSURL)) {
        self.installedNavigationApps.append(url)
} else {
        // do nothing
}
Run Code Online (Sandbox Code Playgroud)

常见的导航应用是:

  • Google地图 - NSURL(字符串:"comgooglemaps://")
  • Waze - NSURL(字符串:"waze://")
  • Navigon - NSURL(字符串:"navigon://")
  • TomTom - NSURL(字符串:"tomtomhome://")

更多信息可以在http://wiki.akosma.com/IPhone_URL_Schemes找到

创建已安装的导航应用程序列表后,您可以呈现UIAlertController:

let alert = UIAlertController(title: "Selection", message: "Select Navigation App", preferredStyle: .ActionSheet)
for app in self.installNavigationApps {
    let button = UIAlertAction(title: app, style: .Default, handler: nil)
    alert.addAction(button)
}
self.presentViewController(alert, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

当然,您需要使用指定的urlscheme在处理程序中添加按钮单击的行为.例如,如果单击Google地图,请使用以下内容:

UIApplication.sharedApplication().openURL(NSURL(string:
            "comgooglemaps://?saddr=&daddr=\(place.latitude),\(place.longitude)&directionsmode=driving")!) // Also from sumesh's answer
Run Code Online (Sandbox Code Playgroud)

只安装了Apple Maps和Google Maps,这将产生如下内容:

在此输入图像描述

  • 链接已经死了 (4认同)
  • 查看https://github.com/zirinisp/PazMapDirections。我目前正在努力。请记住在您的info.plist中添加方案LSApplicationQueriesSchemes (2认同)

Alf*_*lfi 17

斯威夫特 5+

基于@Emptyless 答案。

到

import MapKit

func openMapButtonAction() {
        let latitude = 45.5088
        let longitude = -73.554

        let appleURL = "http://maps.apple.com/?daddr=\(latitude),\(longitude)"
        let googleURL = "comgooglemaps://?daddr=\(latitude),\(longitude)&directionsmode=driving"
        let wazeURL = "waze://?ll=\(latitude),\(longitude)&navigate=false"

        let googleItem = ("Google Map", URL(string:googleURL)!)
        let wazeItem = ("Waze", URL(string:wazeURL)!)
        var installedNavigationApps = [("Apple Maps", URL(string:appleURL)!)]

        if UIApplication.shared.canOpenURL(googleItem.1) {
            installedNavigationApps.append(googleItem)
        }

        if UIApplication.shared.canOpenURL(wazeItem.1) {
            installedNavigationApps.append(wazeItem)
        }

        let alert = UIAlertController(title: "Selection", message: "Select Navigation App", preferredStyle: .actionSheet)
        for app in installedNavigationApps {
            let button = UIAlertAction(title: app.0, style: .default, handler: { _ in
                UIApplication.shared.open(app.1, options: [:], completionHandler: nil)
            })
            alert.addAction(button)
        }
        let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        alert.addAction(cancel)
        present(alert, animated: true)
    }
Run Code Online (Sandbox Code Playgroud)

还将这些放在您的 info.plist 中:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>googlechromes</string>
    <string>comgooglemaps</string>
    <string>waze</string>
</array>
Run Code Online (Sandbox Code Playgroud)

干杯!


Ang*_*qui 10

基于先前答案的 Swift 5+ 解决方案,此解决方案显示了Apple Maps、Google Maps、Waze 和 City Mapper之间的选择。它还允许一些可选的位置标题(对于那些支持它的应用程序),并且仅当有 1 个以上的选项时才显示警报(如果只有 1 个,它会自动打开,或者如果没有,则什么都不做)。

func openMaps(latitude: Double, longitude: Double, title: String?) {
    let application = UIApplication.shared
    let coordinate = "\(latitude),\(longitude)"
    let encodedTitle = title?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
    let handlers = [
        ("Apple Maps", "http://maps.apple.com/?q=\(encodedTitle)&ll=\(coordinate)"),
        ("Google Maps", "comgooglemaps://?q=\(coordinate)"),
        ("Waze", "waze://?ll=\(coordinate)"),
        ("Citymapper", "citymapper://directions?endcoord=\(coordinate)&endname=\(encodedTitle)")
    ]
        .compactMap { (name, address) in URL(string: address).map { (name, $0) } }
        .filter { (_, url) in application.canOpenURL(url) }

    guard handlers.count > 1 else {
        if let (_, url) = handlers.first {
            application.open(url, options: [:])
        }
        return
    }
    let alert = UIAlertController(title: R.string.localizable.select_map_app(), message: nil, preferredStyle: .actionSheet)
    handlers.forEach { (name, url) in
        alert.addAction(UIAlertAction(title: name, style: .default) { _ in
            application.open(url, options: [:])
        })
    }
    alert.addAction(UIAlertAction(title: R.string.localizable.cancel(), style: .cancel, handler: nil))
    contextProvider.currentViewController.present(alert, animated: true, completion: nil)
}
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案使用R.swift进行字符串本地化,但您可以NSLocalizedString正常替换它们,并且它使用 acontextProvider.currentViewController来获取presented UIViewController,但self如果您已经在视图控制器中调用它,则可以将其替换为。

像往常一样,您还需要将以下内容添加到您的应用程序 Info.plist 中:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>citymapper</string>
    <string>comgooglemaps</string>
    <string>waze</string>
</array>
Run Code Online (Sandbox Code Playgroud)


sha*_*zar 8

基于 @Angel G. Olloqui 回答的SwiftUI方法:

struct YourView: View {
    @State private var showingSheet = false

    var body: some View {
        VStack {
            Button(action: {
                showingSheet = true
            }) {
                Text("Navigate")
            }

        }
        .actionSheet(isPresented: $showingSheet) {
            let latitude = 45.5088
            let longitude = -73.554

            let appleURL = "http://maps.apple.com/?daddr=\(latitude),\(longitude)"
            let googleURL = "comgooglemaps://?daddr=\(latitude),\(longitude)&directionsmode=driving"
            let wazeURL = "waze://?ll=\(latitude),\(longitude)&navigate=false"

            let googleItem = ("Google Map", URL(string:googleURL)!)
            let wazeItem = ("Waze", URL(string:wazeURL)!)
            var installedNavigationApps = [("Apple Maps", URL(string:appleURL)!)]

            if UIApplication.shared.canOpenURL(googleItem.1) {
                installedNavigationApps.append(googleItem)
            }

            if UIApplication.shared.canOpenURL(wazeItem.1) {
                installedNavigationApps.append(wazeItem)
            }
            
            var buttons: [ActionSheet.Button] = []
            for app in installedNavigationApps {
                let button: ActionSheet.Button = .default(Text(app.0)) {
                    UIApplication.shared.open(app.1, options: [:], completionHandler: nil)
                }
                buttons.append(button)
            }
            let cancel: ActionSheet.Button = .cancel()
            buttons.append(cancel)
            
            return ActionSheet(title: Text("Navigate"), message: Text("Select an app..."), buttons: buttons)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,将以下内容添加到您的 Info.plist 中

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>googlechromes</string>
    <string>comgooglemaps</string>
    <string>waze</string>
</array>
Run Code Online (Sandbox Code Playgroud)