iOS Tutorial Add QuickActions to your App

Discussion in 'iOS Tutorials' started by JanPRO, Dec 17, 2016.

  1. JanPRO

    JanPRO Well-Known Member Licensed User

    Hi,

    in this thread I want to show you, how to add QuickActions/Shortcuts to your App. QuickActions require 3D touch support and iOS 9 (minimum).

    1.) Download the QuickActions tool, to create a #PlistExtra string (note: you are not allowed, to have more than 4 actions)
    2.) Paste the #PlistExtra string to the project attributes region
    3.) Download the QuickActions module and add it to your project
    4.) Add the following code:

    Code:
    Private Sub Application_Start (Nav As NavigationController)
        QuickActions.StartSettings
        ...
        ...
        ...
    End Sub

    Private Sub Application_Active
        QuickActions.ActiveSettings
    End Sub

    Private Sub Application_Inactive
        QuickActions.InactiveSettings
    End Sub
    5.) To know wheter a shortcut item was clicked, use the ShortcutItemClicked event:
    Code:
    Sub Application_ShortcutItemClicked (ItemType As String)
        
    Log($"QuickAction: ${ItemType}"$)
    End Sub

    If you are using a CustomIcon, put the icon file in to the Special folder.

    If you don't have a iDevice, which supports 3D touch, but a local/virtual mac you can use this tool: https://github.com/PoomSmart/SBShortcutMenuSimulator for tests.

    Feel free to ask questions ;)

    Jan
     

    Attached Files:

    Last edited: Dec 17, 2016
  2. schimanski

    schimanski Well-Known Member Licensed User

    Thank you for this great class!

    I only have one problem: The sub Application_OpenUrl (Url As String, Data As Object, SourceApplication As String) is no longer raised. Do I have to account something else?
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    The QuickActions module replaces the default delegate with its own. A better approach will be to add the required method to the default delegate.

    Add this code to the main module and remove QuickActions module.
    Code:
    #if OBJC
    @end
    @implementation B4IAppDelegate (shortcut)
    -(void)application:(UIApplication *)application
    performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
    completionHandler:(void (^)(BOOL succeeded))completionHandler{
    B4I* bi = [b4i_main new].bi;
    [bi raiseEvent:nil event:@"application_shortcutitemclicked:" params:@[shortcutItem.type]];
    completionHandler(YES);
    }
    #End If
    Add this code after at the end of the main module.
     
    Last edited: Jan 9, 2018
    Pooya1, JordiCP and narek adonts like this.
  4. schimanski

    schimanski Well-Known Member Licensed User

    Thank you very much. With this code, the Application_xxx subs are all raised normaly. But there is now a new problem: I use now 4 OBJC-sections in my main module. With adding your QuickAction code, the other three sections raises now an method not found-exception. For example the exception from the fixorientation-objc-code:

    Code:
    Error occurred on line: 2612 (Main)
    Method 
    not found: fixOrientation:, target: <b4i_main: (null)>
    Stack Trace: (
      CoreFoundation       <redacted> + 
    148
      libobjc.A.dylib      objc_exception_throw + 
    56
      CoreFoundation       <redacted> + 
    0
      EIS                  +[B4I runDynamicMethod:method:throwErrorIfMissing:args:] + 
    388
      EIS                  -[B4INativeObject RunMethod::] + 
    216
      EIS                  -[b4i_main _fixorientation_image:] + 
    1156
      EIS                  -[b4i_main _anhang_bild:] + 
    696
      EIS                  -[b4i_main _kamera_complete:::] + 
    2096
      CoreFoundation       <redacted> + 
    144
      CoreFoundation       <redacted> + 
    292
     EIS                  +[B4I runDynamicMethod:method:throwErrorIfMissing:args:] + 
    1624
     EIS                  -[B4IShell runMethod:] + 
    448
     EIS                  -[B4IShell raiseEventImpl:method:args::] + 
    1784
     EIS                  -[B4IShellBI raiseEvent:
    event:params:] + 1408
     EIS                  +[B4IObjectWrapper raiseEvent:::] + 
    300
     EIS                  -[B4ICameraDelegate imagePickerController:didFinishPickingMediaWithInfo:] + 
    504
     UIKit                <redacted> + 
    128
     UIKit                <redacted> + 
    44
     libdispatch.dylib    <redacted> + 
    24
     libdispatch.dylib    <redacted> + 
    16
     libdispatch.dylib    <redacted> + 
    968
     CoreFoundation       <redacted> + 
    12
     CoreFoundation       <redacted> + 
    2012
     CoreFoundation       CFRunLoopRunSpecific + 
    436
     GraphicsServices     GSEventRunModal + 
    100
     UIKit                UIApplicationMain + 
    236
     EIS                  main + 
    124
     libdyld.dylib        <redacted> + 
    4
    )
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    You must add the OBJC code from the 3rd post at the end of the module.
     
    Last edited: Jan 7, 2018
  6. schimanski

    schimanski Well-Known Member Licensed User

    That's it! Thank you...
     
  7. narek adonts

    narek adonts Well-Known Member Licensed User

    This is a good snippet for objc part. Is there a way like this to add delegate methods for other controls or object like tableview, textfield,... ?
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    This is indeed a nice snippet. You can use it to extend public classes. Many of the delegates classes are private (not declared in the .h file). I wasn't aware to this "trick" in the past. Going forward most of the delegates will be public.
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    This is a great feature to add to your apps. It is very simple (use the OBJC snippet instead of the module) and it adds a nice touch.
    Apple are now more strict with their policies and they might reject apps that lack native features with the explanation that it should have been implemented as a web app.
    I think that this feature can help in such cases.
     
Loading...