Giter Site home page Giter Site logo

kiliankoe / karte Goto Github PK

View Code? Open in Web Editor NEW
108.0 4.0 13.0 192 KB

πŸ—Ί Conveniently launch directions in other iOS apps

License: MIT License

Swift 100.00%
apple-maps navigation-apps url-scheme navigation cocoapod url-schemes action-sheet transport

karte's Introduction

Karte

Travis GitHub tag (latest SemVer)

Small library for opening a location or route in other popular iOS navigation apps.

Currently supported are Apple Maps, Google Maps, Citymapper, Transit, Lyft, Uber, Navigon, Waze, DB Navigator, Yandex.Navi and Moovit.

Know of any other navigation apps that can be opened via URL scheme or universal link? Please open an issue and/or PR πŸ™ƒ

Quick Start

Check if an app is installed.

if Karte.isInstalled(.citymapper) {
    print("Citymapper is installed πŸŽ‰")
}

Launch a specific app with directions.

let coordinate = CLLocationCoordinate2D(latitude: 52.5162746, longitude: 13.3755153)
let berlin = Karte.Location(name: "Brandenburger Tor Berlin", coordinate: coordinate)
Karte.launch(app: .googleMaps, destination: berlin)

Or directly present the user with an action sheet listing all installed navigation apps to pick from.

Karte.presentPicker(destination: location, presentOn: viewController)

If you need more control in how to present the action sheet (e.g. on an iPad), you can get a configured one from Karte without having it presented directly.

let alert = Karte.createPicker(destination: location)

.launch(), .presentPicker() and .createPicker() have a few extra parameters with default values set that you can change to your liking. Most important to note would be an origin location, which can of course also be specified. Leaving it blank defaults to the user's current location in most apps.

A mode of transport can also be specified, which would then filter unsupported apps from the picker. Be aware that trying to launch an app directly with a specific mode of transport will verify if the app supports that mode and throw a Karte.Error.unsupportedMode otherwise.

Caveat

Please be aware that for .isInstalled(), .presentPicker() and .createPicker() to work you will have to have added the necessary URL schemes to your app's Info.plist beforehand. See Apple's Docs for more info on this. The necessary URL schemes can be found here. You're still free to try and launch apps via Karte.launch(app:to:) regardless of registered URL schemes, although that obviously might result in nothing happening if the app isn't there. Don't forget that even Apple Maps can be "uninstalled" now πŸ˜‰

The section to add to your Info.plist should look like this:

<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>comgooglemaps</string>
        <string>citymapper</string>
        <string>transit</string>
        <string>lyft</string>
        <string>uber</string>
        <string>navigon</string>
        <string>waze</string>
        <string>dbnavigator</string>
        <string>yandexnavi</string>
        <string>moovit</string>
    </array>

Installation

Karte is available through SwiftPM. Just copy https://github.com/kiliankoe/Karte into Xcode ✌️

Credits

This library is based on CMMapLauncher. Unfortunately development on that library seems to have been stopped, so this is a reimplementation in Swift including a few changes and other apps to make usage even more pleasant 😊

Authors

Kilian Koeltzsch, @kiliankoe

"Karte"?

It's German for "Map" and that seemed fitting πŸ€·β€β™€οΈ

karte's People

Contributors

guykogus avatar inickt avatar kiliankoe avatar lightsprint09 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

karte's Issues

Universal links

Universal links have become the defacto standard anyway, but it's not an option for all apps. And they're rather incompatible with isInstalled(), but I guess that's pretty obvious, so πŸ€·β€β™‚οΈ

Am I right in thinking Google Maps is the only candidate for this at the moment?

Crash on iPad

ItΒ΄s me again πŸ˜ƒ Todays issue: When presenting the picker on an iPad, the app crashes with this error:

Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0x7fe137a00600>) of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'

and a for every available app this log before it crahes:
-canOpenURL: failed for URL: "moovit://" - error: "Der Vorgang konnte nicht abgeschlossen werden. (OSStatus-Fehler -10814.)"

actionSheet issue with presentPicker Xcode 11

Hello,

I'm trying to use presentPicker with action sheet, it works but when I return app, title and message stays and can't close the action sheet. Here is my code

@IBAction func navigationTapped(_ sender: Any) {
       let coordinate = CLLocationCoordinate2D(latitude: 52.5162746, longitude: 13.3755153)
       let berlin = Karte.Location(name: "Brandenburger Tor Berlin", coordinate: coordinate)
       let actionSheetVC = UIAlertController(title: "Title", message: "Please Select an Option", preferredStyle: .actionSheet)
       

       self.present(actionSheetVC, animated: true)
       Karte.presentPicker(destination: berlin, presentOn: actionSheetVC)
   }

When I clicked button it shows up available maps;
IMG_9714

When I return app screen looks like this;
IMG_9715

Am I using action sheet with wrong way?

Does not work on iPad

The alert view can't be presented on an iPad, when style = .actionSheet is used.

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0x105272a00>) of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'
*** First throw call stack:

Default open when there is only one app available

It would be cool if the picker would automatically open the location if there is only one app in the list. Also the case of no app installed should be handled in some way.

But nice work and great naming of the library ;-)

iOS 9 Support

Hi. I was looking at using this library for the open list functionality and it looks exactly what I wanted. However, I still target iOS 9 in our app.

Would it be possible to add iOS 9 support? I don't know if there are any methods added in iOS 10 that are required.

'Error' is ambiguous for type lookup in this context

This simple code leads to a compiler error: 'Error' is ambiguous for type lookup in this context

import Karte
class CompilterTest {
    var test: Error?
}

The reason is that Karte makes the type ambiguous:

import Foundation
public enum Error: Swift.Error {
    case unsupportedMode
}

It would make code that uses Karte much nicer if it could use the type Error as usual.

Google Maps does not work if location has coordinates and name

Try to open this location with Google Maps:

Location(name="Cumberland Gap", coord={lat:36.6027371, lng:-83.6953039})

Google Maps displays the error message "Can't seem to find that place". In the destination field you can read "36.6027371,-83.6953039 (Cumberland Gap)"

Setting name to nil works, though.

Location(name=nil, coord={lat:36.6027371, lng:-83.6953039})

Having a name would be nice. This works for Apple Maps. For now I have to omit the name to make it work.

Convert to Swift 4.2

Updated my app to 4.2 and it looks like it should be pretty straightforward with minimal changes needed.

Make App.all public

We'd like to do what #21 suggests directly in our app by simply checking which apps are installed.

Unfortunately the following won't work because .all isn't public:

let apps = App.all.filter(Karte.isInstalled)
if apps.count == 1 { … }

Assign rawValus to Enums

I'd like to have an easy way to store App and Mode in UserDefaults.

A common way to to this is to store raw values and create the Enum instances from the raw value like

    let test1 = App(rawValue: 0)
    let test2 = App(rawValue: "appleMaps")

At the moment, the Enums in Karte don't support this, because they're not assigned to a raw value like

public enum App: int {

or

public enum App: String {

Please consider App and Mode as Int or String to make it easy to store those values in UserDefaults

Rename App

Thanks for the nice library!

Unfortunately just like #28 the name App is way too generic and causes an unresolvable collision for us.

Either App should be renamed to KarteApp / NavigationApp / … or public enum Karte should be renamed to something different from the module so that any kind of conflict can be resolved e.g. by using Karte.App.

Or maybe nest App and Location etc inside the Karte enum so that everything must always be qualified (Karte.Location, Karte.App etc.)

Show one location w/o directions

Would be nice to support also. It does make a bit of a difference for some URL schemes though afaict compared to just leaving off the origin location.

SwiftUI

Would be nice to add support for showing the pre-made action sheet from SwiftUI.

handle uninstalled Apple Maps

Putting a wink emoji in the readme and not respecting the hint myself is some kind of next-level smug. isInstalled() short circuits to true if querying for Apple Maps. How can I check that though? UIApplication.shared.canOpenURL() seems to report true for maps:// and http://maps.apple.com/?q=[...] even if Maps.app is "removed" (as in disabled) from a user's device.

See πŸ“‘ rdar://31680034

Rename Location as KarteLocation

Hi there,

Thanks for making this great library. I was wondering though whether you could rename public struct Location {} into public struct KarteLocation {}. We are using a custom Location class in our code and using Karte creates a naming collision with this class.

Thanks in advance.

Karte Does not compile with destination Apple Vision Pro

Karte does not compile with destination 'Apple Vision Pro' (Destination Apple Pro /Designed for iPad is no problem.

Problem is this code in enum Karte:

    if #available(iOS 10.0, *) {
        UIApplication.shared.open(url, completionHandler: nil)
    } else {
        UIApplication.shared.openURL(url)
    }

UIApplication.shared.openURL(url) isn't available in visionOS

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.