An easier way to handle third-party URL schemes in iOS apps.

Overview

IntentKit Build Status Coverage Status

=========

IntentKit is an easier way to handle third-party URL schemes in iOS apps.

Example of activity view

Linking to third-party apps is essentially broken on iOS. Let's say that, as a developer, you want to allow users to open map links in Google Maps instead of the built-in Maps.app. You now need to write a whole bunch of custom code that determines whether Google Maps is installed, ask the user which they would prefer, and ideally remember that preference.

If we take a more complex example, like Twitter clients, you're now potentially managing a dozen different third-party URL schemes that are all drastically different and quite possibly poorly-documented.

As a result, very few apps link to external third-party apps for tasks handled by Apple's easier-to-link-to apps, even when users prefer third-party apps.

IntentKit attempts to solve this problem.

For users, it provides a beautiful selection interface to choose which third-party app to perform an action in.

For developers, it provides:

  • An elegant, cohesive API based on semantic actions. Instead of manually constructing URLs or creating modal view controllers to display, just tell it what you're trying to do. Instead of manually checking which applications a user has installed, let IntentKit automatically query the device for you to figure out what applications are available to perform a given action.

  • A unified, human-readable repository of third-party URL schemes. Every application's URL scheme is just a plaintext plist. You can add support for your application to IntentKit without writing a single line of code.

Installation

IntentKit is easiest to install using CocoaPods. Just add the following to your Podfile.

pod "IntentKit"

After running pod install, you should be able to #import any INKHandler header file (e.g. #import ) and go to town.

If you're concerned about the increase in your app bundle's size, you can choose to only include a subset of IntentKit's supported applications. Subspecs exist for each handler class.

# Only includes web browsers
pod "IntentKit/Browsers"

For more information on what subspecs are available, refer to the project's Podspec.

URL Schemes and Info.plist

As of iOS 9, Apple requires you to whitelist all third-party URL schemes you plan to use in-app. This means that using IntentKit requires adding all URL schemes it might use to your info.plist file, as an array with the key LSApplicationQueriesScheme. For example, here's what it looks like to add support for Google Maps.

<key>LSApplicationQueriesSchemeskey>
<array>
    <string>comgooglemapsstring>
    <string>comgooglemaps-x-callbackstring>
array>

For now, you'll have to manually look up which URL schemes the IntentKit handlers you are using might query (check the various plist files nested within the Apps folder. We recognize that sucks. In the future, IntentKit might provide either a definitive list of which URL schemes are necessary per-handler, or even a way to automate adding this to your Info.plist.

Swift

IntentKit works great in both Swift and Objective-C.

If you're using Swift, it's recommended you have the use_frameworks! option enabled in CocoaPods. From there, just import IntentKit (or an equivalent subspec) from whatever Swift file you want to use IntentKit in.

Usage

To use IntentKit, you start by instantiating a handler object. There are a handful of handler objects that come with IntentKit, each with domain knowledge of a specific type of application. For example, INKBrowserHandler, INKMapsHandler, and INKTwitterHandler handle opening links in web browsers, mapping applications, and Twitter clients, respectively.

After creating a new handler object, you just tell it what action you want to perform. It will return you a special object called a presenter, which can be used to actually perform the action. Here's how you'd open an email compose screen on an iPhone:

INKMailHandler *mailHandler = [[INKMailHandler alloc] init];
[[mailHandler sendMailTo:@"[email protected]"] presentModally];

If the user doesn't have any third-party mail apps installed (such as Mailbox or Google's native Gmail app), this will display an in-line MFMailComposeViewController, just as if you had created and presented one yourself. If the user does have other mail apps installed, this will display a modal sheet that looks like a UIActivityViewController listing each available application. It will also give them a switch they can tap to remember their choice for all future links of that type.

"Convention Over Configuration" mode

Depending on your application and userbase, that user experience might not be ideal. If 99% of your users want to use the Apple default, why should they have to go through an extra tap?

Each INKHandler object has an useSystemDefault property. If you set it to YES, performing an INKHandler action will not result in a custom UI being shown. Instead, the system will silently pick an application to handle the request. Sensible defaults are picked for each handler type: all handlers that have an Apple-provided application will use that one, and handlers that are based on a third-party service (e.g. Twitter) will default to using the first-party application.

If you use this method of presenting IntentKit, it's recommended that you give users a way to set their own defaults. IntentKit provides a view controller called INKDefaultsViewController that lets users set preferences. Just create a new INKDefaultsViewController object, optionally limit which handler types should be displayed, and present it on-screen:

INKDefaultsViewController *defaultsController = [[INKDefaultsViewController alloc] init];
defaultsController.allowedHandlers = @[[INKBrowserHandler class], [INKMailHandler class]];
[self pushViewController:defaultsController animated:YES];

When you don't manually limit the handler types, it looks something like this:

Example of defaults selector

If you'd rather more control over the user experience, IntentKit also offers API hooks to set your own defaults. Every INKHandler object has a promptToSetDefault method that will return an INKActivityPresenter object that handles prompting the user to select an application. For even lower-level control, the INKApplicationList and INKDefaultsManager classes can be used to fetch a list of available applications and manually set defaults.

Optional Parameters

Some handlers have optional configuration parameters. For example, when linking to a map application, you can specify where the map should be centered and how zoomed-in it should be; these options will take effect whether you're searching for a location, getting turn-by-turn directions, or doing any other action supported by the handler.

INKMapsHandler *mapsHandler = [[INKMapsHandler alloc] init];
mapsHandler.center = CLLocationCoordinate2DMake(42.523, -73.544);
mapsHandler.zoom = 14;
[mapsHandler directionsFrom:@"Washington Square Park" to:@"Lincoln Center"];

This is where the real power of IntentKit shines through. This gives you a clean, semantic API to construct links rather than having to manually cobble together URLs, regardless of whether your user wants to use Apple Maps or a third-party app.

An up-to-date list of available handlers and what methods and configuration options is available in the project's documentation.

Explicitly specifying the view controller

If you're using presentModally, it will attempt to intelligently figure out which view controller to present itself on. It's possible it won't pick the correct one automatically; if that's the case, you probably want to explicitly specify the correct view controller.

NSURL *url = [NSURL URLWithString:@"http://www.google.com/"]
INKBrowserHandler *browserHandler = [[INKBrowserHandler alloc] init];
INKActivityPresenter *presenter = ][browserHandler openURL:url];
[presenter presentModalActivitySheetFromViewController:self];

iPad and UIPopoverController

If your app is Universal or iPad-only, if you're displaying an IntentKit INKActivityViewController you probably want to display it as a popover instead of a modal sheet. The following code will automatically display itself modally on an iPhone and in a UIPopoverController on an iPad.

NSURL *url = [NSURL URLWithString:@"http://www.google.com/"]
INKBrowserHandler *browserHandler = [[INKBrowserHandler alloc] init];
INKActivityPresenter *presenter = [browserHandler openURL:url];
[presenter presentActivitySheetFromViewController:self
                                  popoverFromRect:someRect
                                           inView:self.view
                         permittedArrowDirections:UIPopoverArrowDirectionAny
                                         animated:YES];

All of those options will be passed directly into a UIPopoverController. Similarly, there exists a presentActivitySheetFromViewController:popoverFromBarButtonItem:permittedArrowDirections:animated: method that calls the equivalent UIPopoverController method if appropriate.

Fallback URLs

If a user doesn't have any appropriate apps installed that can perform an action, IntentKit will try to use a web browser as a fallback. For example, if a user tries to do something involving Twitter but doesn't have a Twitter client installed, IntentKit will try to load the appropriate twitter.com URL. It does this by presenting an INKBrowserHandler so the user can still pick their preferred web browser.

If you don't want this behavior, you can disable it by setting a handler's useFallback property to NO before invoking an action.

Safari and UIWebViews

It's worth mentioning that IntentKit's default web browser is an in-app modal UIWebView. This is true both for actions triggered by an INKBrowserHandler and actions triggered by other handlers falling back to a web URL. If you don't want to do that, and would rather fall back on Safari for web actions, you can set your handler's disableInAppOption property to NO.

Documentation

Documentation can be viewed online on CocoaDocs.

Alternatively, documentation can be found in the docs directory by running script/generate-docs.sh from the root directory. If you do this, be aware that the documentation will be generated from your current copy of the code, which might differ from the most recent tagged version on CocoaPods.

Example Project

A demo app has been provided so you can see IntentKit in action.

  1. Clone this repo.
  2. Run pod install inside the project directory.
  3. Open Example/IntentKitDemo.xcworkspace.
  4. Build and run the app.

The demo lets you perform any of the actions supported by IntentKit.

If you only have one app installed capable of performing a task, IntentKit will by default open up that app directly rather than prompt the user to pick. In the demo app, there is a toggle to always show the selection UI if there is at least one application available. It's recommended that you run the demo on an actual iOS device that has third-party apps installed, but if you must run it in the simulator that toggle will let you see what the selection UI looks like.

Adding Your Own Actions

Extending IntentKit is easy.

Including your own URL Scheme

  1. Inside the IntentKit/Apps/ directory, create a new directory with the name of your app.

  2. Inside that directory, create a plist. Its name should be the app's (English) name, and its root object should be a dictionary.

    Inside this dictionary, there should be a name key that represents the app's localized name(s). If your app's name does not change across locales, its value should be a string with that name.

    <key>namekey>
    <string>Safaristring>

    If it does change, the value should be a dictionary mapping IETF BCP 47 language identifiers to localized names.

    <key>namekey>
    <dict>
      <key>enkey>
      <string>Sina Weibostring>
      <key>zh-Hanskey>
      <string>新浪微博string>
    dict>

    Additionally, there should be an actions dictionary containing all of the actions your application can perform. This dictionary should map strings representing INKHandler methods to template strings used to generate URLs for those method. In these template strings, variables wrapped in Mustache-style curly braces will be interpolated at runtime. Just like Mustache, variables wrapped in double-braces ({{name}}) will be URL-escaped, whereas ones wrapped in triple-braces ({{{url}}}) will not be. For example:

    <key>actionskey>
    <dict>
        <key>searchForLocation:key>
        <string>comgooglemaps://?q={{query}}string>
    dict>

    In general, the template variable keys are named the same as the argument names of the corresponding handler methods, but there is currently nothing enforcing that. It's recommended that you look at the plist files for other apps that respond to the same actions to see what the correct template keys are.

If your application supports actions not currently represented in a handler, or is part of a class of applications that doesn't currently have a handler, you'll have to write code to add support. The current handler code is easy to read; refer to an existing handler subclass as a reference for creating your own handler methods or INKHandler subclasses.

  1. Your app's icon goes in the same directory. You will need four copies of the icon, all with the same root name as your plist file:

    • AppName.png: 60x60
    • AppName~ipad.png: 76x76
    • [email protected]: 120x120
    • AppName@2x~ipad.png: 152x152

    Use the same square icons you're using in your app's Xcode project; IntentKit will take care of masking them so they appear as iOS-style rounded rectangles/superellipses. The root filename ("AppName" in those examples) must exactly match the filename of the plist.

  2. In the root of your IntentKit codebase, run pod install. This will cause Xcode to pick up any new files you've added. Next, run rake to run the test suite, which includes a linter to make sure that every action you've defined in your plist corresponds to a valid handler action. You'll also probably want to run the example app on an actual iOS device to make sure your links all work as expected.

  3. In IntentKit.podspec, add your app to the subspec that corresponds to the handler your application responds to. Just add your app's folder name to the list of other application folder names in the appropriate resource bundle file glob.

  4. Submit a pull request!

Including Your Own In-App View Controller

Adding your own modal in-app action is very similar to adding your own URL scheme, with a few exceptions.

All presentable IntentKit activities must conform to the INKPresentable protocol, which defines two methods: one which returns whether or not it can perform a given action, and tells it to actually perform an action. The latter method is passed a view controller to present your view controller modally on; it should both present your view controller, and take care of dismissing it once your action is complete.

A few other changes must be made to your application's IntentKit plist file:

  1. actions should be an array of action names, rather than a dictionary.

  2. There should be a field called className that lists the name of your INKPresententable class.

  3. The name field should refer to whatever you want the activity to be listed as inside the app. For example, INKMailSheet (the activity that displays a MFMailComposeViewController) has a name of "In App".

Requirements

IntentKit requires Xcode 5, targeting iOS 7.0 and above.

Contributing

All contributions are welcome! If you want to help but don't know where to begin, adding in support for a new third-party application can be a great way to get started (it typically doesn't require writing any code).

Tests and documentation are heavily encouraged for new code. We use appledoc for documentation and Specta) for tests.

Roadmap

The goal of the initial version of IntentKit was just to create a simple way to integrate third-party app linking without a lot of boilerplate code. Here's a non-exhaustive list of ways it could be extended in to the future.

  • Downloading and caching plists at runtime, allowing an app to pull in the latest URL schemes without needing an App Store update
  • A web-based CMS to add and manage URL schemes without needing to manually edit plists or submit pull requests.
  • Saving user app preferences across all applications on a single device that use IntentKit
  • Optional downloading of app icons from Apple at runtime rather than requiring developers to upload them

Contact

Mike Walker

The initial version of IntentKit was built at Hacker School.

License

IntentKit is available under the MIT license. See the LICENSE file for more info.

Comments
  • Demo app can't compile

    Demo app can't compile

    These are the errors:

    diff: /../Podfile.lock: No such file or directory diff: /Manifest.lock: No such file or directory error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

    I also tried to update the pod but it also has an error:

    NoMethodError - undefined method []' for #<Xcodeproj::Project::Object::PBXFileReference:0x007f8249322260> /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/project.rb:186:inblock in add_file_reference' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/pathname.rb:263:in block in each_filename' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/pathname.rb:263:ineach' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/pathname.rb:263:in each_filename' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/project.rb:184:inadd_file_reference' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:168:in block (2 levels) in add_file_accessors_paths_to_pods_group' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:166:ineach' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:166:in block in add_file_accessors_paths_to_pods_group' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:162:ineach' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:162:in add_file_accessors_paths_to_pods_group' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:104:inblock in add_resources' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/user_interface.rb:110:in message' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:102:inadd_resources' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer/file_references_installer.rb:38:in install!' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer.rb:486:ininstall_file_references' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer.rb:130:in block in generate_pods_project' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/user_interface.rb:49:insection' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer.rb:128:in generate_pods_project' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/installer.rb:96:ininstall!' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/command/project.rb:71:in run_install_with_update' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/command/project.rb:101:inrun' /Library/Ruby/Gems/2.0.0/gems/claide-0.8.1/lib/claide/command.rb:312:in run' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/lib/cocoapods/command.rb:46:inrun' /Library/Ruby/Gems/2.0.0/gems/cocoapods-0.36.0/bin/pod:44:in <top (required)>' /usr/bin/pod:23:inload' /usr/bin/pod:23:in `

    '

    opened by markfulo 10
  • After tapping on an App, ViewController history is erased

    After tapping on an App, ViewController history is erased

    Real use case. Hierarchy (indented are subviews / childviewcontroller):

    • Root1 UIViewController
      • Root2 UINavigationViewController
        • Table1 UITableViewController

    Now I present a modal UINavigationViewController with a UITableViewController from the Root2 controller. From this modally presented controller I call handleUrl method. No selection is shown (correct, only one app is installed, so no selection), I go to (for example, Tweetbot). When I now return through multitasking, I'am in the UITableViewController (correct, as well), but if I close this, I just get a blank canvas, from the Root1 controller. viewDidAppear is called there, however, nothing displayed. Root2 and Table1 controllers aren't nil, but [controller view] window] is NULL. From this point the app has to be restarted to work correctly.

    I checked everything in the application, no memory leaks, the controller aren't garbage collected, correctly retained. I debugged the application for two hours straight, the errors has to be related to the library in someway.

    Hopefully it's understandable. :D

    bug 
    opened by Leandros 9
  • An Avatar for the Organization

    An Avatar for the Organization

    I thought that IntentKit needed a simple avatar, so I quickly put this together in illustrator. It's the icon for action sheets.

    (Click on it for the 1k x 1) <a href=https://f.cloud.github.com/assets/3122471/1761213/baba4b0a-66c6-11e3-9c4a-1b4171c0e3e9.png'>

    I have it as a vector so I can change anything/everything if need be. Thanks!

    opened by ruddfawcett 9
  • iOS 9 broke the application picker

    iOS 9 broke the application picker

    After updating to iOS 9, IntentKit can't find other alternatives to the default application. Let's say I want to present the Map Handler on my iPhone with both Waze and Google Maps installed.

    Having this method called:

    - (void)openMapWithDirectionsFrom:(NSString *)fromString to:(NSString *)toString {
        INKMapsHandler *handler = [INKMapsHandler new];
        INKActivityPresenter *presenter = [handler directionsFrom:fromString to:toString mode:INKMapsHandlerDirectionsModeWalking];
        [presenter presentModallyWithCompletion:^{
            [self.view removeFromSuperview]; 
        }];
    }
    

    I get the following logs on the console:

    2015-09-22 12:41:17.185 App[1087:471378] -canOpenURL: failed for URL: "comgooglemaps://" - error: "This app is not allowed to query for scheme comgooglemaps"
    2015-09-22 12:41:17.191 App[1087:471378] -canOpenURL: failed for URL: "waze://" - error: "This app is not allowed to query for scheme waze"
    

    This is a new feature or bug by Apple. More information can be found here.

    To let the user choose their favorite mapping service we must add a new key to the Info.plist as follows.

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>waze</string>
        <string>comgooglemaps</string>
    </array>
    
    opened by asalom 8
  • Activity sheet does not show the app icons

    Activity sheet does not show the app icons

    Hi

    When I present the Activity sheet it does not show the app icons. It has the App label there and it works when pressed but no icon. Any idea on what I am doing wrong?

    Any help much appreciated.

    Svend

    2014-01-19 15 14 05

    opened by stagis 7
  • NSString+Helpers - NSArray to va_list arguments and string format XCode 8

    NSString+Helpers - NSArray to va_list arguments and string format XCode 8

    • (id)stringWithFormat:(NSString )format array:(NSArray)arguments { NSRange range = NSMakeRange(0, [arguments count]); NSMutableData* data = [NSMutableData dataWithLength:sizeof(id) * [arguments count]]; [arguments getObjects:(__unsafe_unretained id *)data.mutableBytes range:range];

      NSString* result = [[NSString alloc] initWithFormat:format arguments:data.mutableBytes]; return result; }

    Since update to xcode 8, I'm receiving EXC_BAD_ACCESS.

    It may be connected with problem that some values passed in array are NSTaggedPointerString * but I'm not sure. Any ideas?

    opened by pgawlowski 6
  • pod

    pod "IntentKit/Maps" does show Google Maps

    After integrating the library with a project, It does not show Google Maps though it is installed in the iPhone.** The Library works perfectly fine in iPad showing both native "Apple Maps" and Installed Google Maps. **. Hope you people can track this issue and find its solution.

    opened by ptejas26 6
  • How to use custom

    How to use custom "App" extensions

    i download the demo source code and was able to introduce two new intents for handling phone numbers, "call" and "message"

    These are currently included in the demo source base I have locally.

    Now I'm curious about how I might get these included in my projects. I'm assuming I can install the IntentKit via pods on my project and simply included the required source files and properties files in a "App" directory in my source and the IntentKit pick it up

    opened by RustyKnight 6
  • Using Subspecs to Modularize Application Support

    Using Subspecs to Modularize Application Support

    Although the current set of applications is pretty manageable at the moment, it will eventually become excessive to include every application with every install (those icon files really add up).

    Cocoapods subspecs offer an elegant way to modularize out functionality, allowing the consumer to specify only what they need. The proposed patch organizes apps into top level groups, representing intents, and then a sub-subspec for each individual application. This allows for the following:

    Podfile

    pod 'MWOpenInKit' # Works the same as before
    pod 'MWOpenInKit/Twitter' # Only include Twitter apps
    pod 'MWOpenInKit/Twitter/Tweetbot' # Only include Tweetbot
    

    I still have a few lingering concerns that I'd like to get some feedback on:

    1. Categorizing sets an important precedent. It's important to make sure the way everything is named and carved up is something we won't eventually regret.
    2. This could be further spec'd out to only include relevant handlers for each category. The correct relationship between these categories and handlers would be something to dwell upon.
    3. CocoaPods 0.23.0 introduced the resource_bundle method, which is perfect for this purpose, but seems to lack the first-class support resources does. If we run pod lint on this, we get:
    - ERROR | [iOS] The MWOpenInKit/Browsers/Chrome (0.1.0) spec is empty (no source files, resources, preserve paths, , vendored_libraries, vendored_frameworks dependencies or sub specs).
    

    This is either something Cocoapods still needs to implement, or I could be misunderstanding how this feature should work.

    opened by mattt 6
  • Remember user's choice within an app

    Remember user's choice within an app

    Presumably this could just be stored in NSUserDefaults for starters, with a checkbox being displayed on top of the activity sheet (unchecked by default).

    There should also be an API method to clear out saved preferences.

    enhancement 
    opened by lazerwalker 6
  • Fixed import of MWLayoutHelpers in INKDefaultsCell and INKAppIconView and duplicate symbols for ink_urlEncode

    Fixed import of MWLayoutHelpers in INKDefaultsCell and INKAppIconView and duplicate symbols for ink_urlEncode

    Fixed import of MWLayoutHelpers in INKAppIconView.m and INKDefaultsCell.m, Other files with this import are already fixed.

    Also fixed compiler error: duplicate symbols for ink_urlEncode

    opened by patrickkempff 4
  • iPhone X support, Stock Mail app name & french translation

    iPhone X support, Stock Mail app name & french translation

    I noticed the following issues regarding the INKMailHandler UI :

    • iPhone X support is not good,
    • the Stock mail app name is bad (INKMailShe...),
    • and there is no french translation.

    Here is a screenshot illustrating the issues.

    img_72780722b78b-1

    I will do a PR soon to fix this. 😉

    opened by nverinaud 1
  • Improved maps support

    Improved maps support

    Improvements:

    • Added new action on map handler to open a location with a name and coordinate. Note that existing actions do not allow to open a random location with a title (it either opens a from/to in route mode or makes a text query)
    • Added citymapper
    • Added search action for waze
    • Translated Maps to Spanish
    opened by angelolloqui 0
  • Figure out how to automate info.plist URL schemes

    Figure out how to automate info.plist URL schemes

    Manually having to add URL schemes after they show up in error logs is subpar. I'd like to find some way to (optionally) automate adding URL schemes to your info.plist file.

    opened by lazerwalker 0
  • Add more maps handlers

    Add more maps handlers

    I'd like to include everything supported in https://github.com/citymapper/CMMapLauncher

    • Citymapper
    • Navigon
    • The Transit App
    • Waze
    • Yandex Navigator

    Citymapper is the highest priority.

    opened by lazerwalker 1
  • Add instructions on how to pull app icon images out of existing app bundles

    Add instructions on how to pull app icon images out of existing app bundles

    To add an app to IntentKit, you need to add that app's icons.

    If you're submitting your own app, it's easy to get your base assets. For people submitting other people's apps, I should include a bit in the README about how I get the assets out of the IPAs.

    opened by lazerwalker 0
🎯Linker Lightweight way to handle internal and external deeplinks in Swift for iOS

Linker Lightweight way to handle internal and external deeplinks in Swift for iOS. Installation Dependency Managers CocoaPods CocoaPods is a dependenc

Maksim Kurpa 128 May 20, 2021
A splendid route-matching, block-based way to handle your deep links.

DeepLink Kit Overview DeepLink Kit is a splendid route-matching, block-based way to handle your deep links. Rather than decide how to format your URLs

Button 3.4k Dec 30, 2022
Eugene Kazaev 713 Dec 25, 2022
SwiftRouter - A URL Router for iOS, written in Swift

SwiftRouter A URL Router for iOS, written in Swift, inspired by HHRouter and JLRoutes. Installation SwiftRouter Version Swift Version Note Before 1.0.

Chester Liu 259 Apr 16, 2021
iOS routing done right. Handles both URL recognition and controller displaying with parsed parameters. All in one line, controller stack preserved automatically!

Developed and Maintained by Ipodishima Founder & CTO at Wasappli Inc. (If you need to develop an app, get in touch with our team!) So what is this lib

null 589 Dec 24, 2022
URL routing library for iOS with a simple block-based API

JLRoutes What is it? JLRoutes is a URL routing library with a simple block-based API. It is designed to make it very easy to handle complex URL scheme

Joel Levin 5.6k Jan 6, 2023
Monarch Router is a Declarative URL- and state-based router written in Swift.

Monarch Router is a declarative routing handler that is capable of managing complex View Controllers hierarchy transitions automatically, decoupling View Controllers from each other via Coordinator and Presenters. It fits right in with Redux style state flow and reactive frameworks.

Eliah Snakin 31 May 19, 2021
URLScheme router than supports auto creation of UIViewControllers for associated url parameters to allow creation of navigation stacks

IKRouter What does it do? Once you have made your UIViewControllers conform to Routable you can register them with the parameters that they represent

Ian Keen 94 Feb 28, 2022
Appz 📱 Launch external apps, and deeplink, with ease using Swift!

Appz ?? Deeplinking to external applications made easy Highlights Web Fallback Support: In case the app can't open the external application, it will f

Kitz 1.1k May 5, 2021
⛵️ URLNavigator provides an elegant way to navigate through view controllers by URLs.

URLNavigator ⛵️ URLNavigator provides an elegant way to navigate through view controllers by URLs. URL patterns can be mapped by using URLNavigator.re

Suyeol Jeon 2.6k May 27, 2021
RxFlow is a navigation framework for iOS applications based on a Reactive Flow Coordinator pattern

About Navigation concerns RxFlow aims to Installation The key principles How to use RxFlow Tools and dependencies GitHub Actions Frameworks Platform L

RxSwift Community 1.5k May 26, 2021
Provides a custom presentation modifier that provides more options including full screen presentations. (iOS)

Presentation Also available as a part of my SwiftUI+ Collection – just add it to Xcode 13+ Provides a custom presentation modifier that provides more

SwiftUI+ 15 Dec 3, 2022
Marshroute is an iOS Library for making your Routers simple but extremely powerful

Marshroute Contents Overview Detailes Tuning the transition animation 3d touch support PeekAndPopUtility Peek and pop state observing Demo Requirement

avito.tech 215 Jan 4, 2023
🛣 Simple Navigation for iOS

Router Reason - Get Started - Installation Why Because classic App Navigation introduces tight coupling between ViewControllers. Complex Apps navigati

Fresh 457 Jan 4, 2023
An extremely lean implementation on the classic iOS router pattern.

Beeline is a very small library that aims to provide a lean, automatic implementation of the classic iOS router pattern.

Tim Oliver 9 Jul 25, 2022
Demonstrate a way to build your own line chart without using any third-party library

LineChart This code demonstrate a way to build your own line chart without using any third-party library. It contains a simple yet effective algorithm

Van Hung Nguyen 0 Oct 17, 2021
GitHub iOS client with minimum third-party dependencies.

GitHubSearch GitHub iOS client with minimum third-party dependencies. The app allows for searching for repositories using GitHub API. ?? In the next r

Eugene Karambirov 38 Dec 29, 2022
Integrate third party libraries by using Cocoapods and Swift Package Manager, store data in the cloud using Firebase Firestore.

Integrate third party libraries by using Cocoapods and Swift Package Manager, store data in the cloud using Firebase Firestore. Exercising query and s

WEI 0 Dec 19, 2021
CryptoExchange - A fully functional structure for Crypto Exchange app without using many third party assests

cryptoExchange A fully functional structure for Crypto Exchange app without usin

Shwait Kumar 0 Jan 6, 2022
A macOS menu bar app that enables system-wide navigation functionality for side buttons on third-party mice.

SaneSideButtons macOS mostly ignores the M4/M5 mouse buttons, commonly used for navigation. Third-party apps can bind them to ⌘+[ and ⌘+], but this on

Jan Hülsmann 121 Dec 23, 2022