How to communicate between iOS App Containing Extension and Extension (not Host App)

后端 未结 4 1370
攒了一身酷
攒了一身酷 2021-01-30 17:46

TLDR: Is it possible to send realtime messages or notifications between iOS App and it\'s Extension?

I\'m writing an iOS App with an extension

相关标签:
4条回答
  • 2021-01-30 18:17

    There is a hack that you can use to communicate between any two apps in iOS or app and extension. The only thing - it doesn't work with NetworkExtension since Apple is blocking any I/O in it.

    You can post notification to the DarwinNotificationCenter this way:

        let notificationName = CFNotificationName("com.notification.name" as CFString)
        let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
    
        CFNotificationCenterPostNotification(notificationCenter, notificationName, nil, nil, false)
    

    In your app add observer:

        let notificationName = "com.notification.name" as CFString
        let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
    
        CFNotificationCenterAddObserver(notificationCenter,
                                        nil,
                                        { (
                                            center: CFNotificationCenter?,
                                            observer: UnsafeMutableRawPointer?,
                                            name: CFNotificationName?,
                                            object: UnsafeRawPointer?,
                                            userInfo: CFDictionary?
                                            ) in
    
                                            print("Notification name: \(name)")
                                        },
                                        notificationName,
                                        nil,
                                        CFNotificationSuspensionBehavior.deliverImmediately)
    

    Some links: https://github.com/choefele/CCHDarwinNotificationCenter

    https://developer.apple.com/documentation/corefoundation/1542572-cfnotificationcentergetdarwinnot

    https://developer.apple.com/library/content/documentation/Darwin/Conceptual/MacOSXNotifcationOv/DarwinNotificationConcepts/DarwinNotificationConcepts.html

    0 讨论(0)
  • 2021-01-30 18:22

    I've been struggling with the same issue and haven't found a clean solution either. Another hacky way to solve this is to simply run a timer in the extension and check the values in the shared container preferences/database periodically and then update if required. Not elegant, but it seems to work.

    0 讨论(0)
  • 2021-01-30 18:25

    For an alternative means of doing general-purpose bidirectional communication between host app and app extension, try MMWormhole:

    http://www.mutualmobile.com/posts/mmwormhole https://github.com/mutualmobile/MMWormhole

    It’s a fairly lightweight wrapper around CFNotificationCenter, and uses “Darwin” notifications to do interprocess communication (IPC).

    It passes payloads back & forth using the apps’ shared container, and encapsulates even having to create the file(s) themselves.

    The class (and the sample app in the repo) seem to work well, and are quite responsive.

    I hope this also helps.

    0 讨论(0)
  • 2021-01-30 18:26

    TLDR: No, but there's a hack

    There's no true interprocess communication for iOS apps, with or without extensions. NSDistributedNotification still hasn't made the trip from OS X to iOS, and probably won't.

    With some extension types you can open URLs via NSExtensionContext and use them to pass data to an app that handles the URL. This brings the app to the foreground, which doesn't sound like what you want.

    There is a hack that might get you what you need, though.

    • Instead of writing to user defaults, write to a file in your app group directory.
    • Don't just write the file directly-- use NSFileCoordinator to do coordinated writes to the file.
    • Implement NSFilePresenter on an object that wants to know about changes to the file, and make sure to call [NSFileCoordinator addFilePresenter:someObject]
    • Implement the optional presentedItemDidChange method on your file presenter.

    If you do all of this right, you can write to this file from either the app or the extension, and then have presentedItemDidChange be automatically called in the other one. As a bonus you can of course read the contents of that file, so you can pass arbitrary data back and forth.

    0 讨论(0)
提交回复
热议问题