簡體   English   中英

如何在iOS App包含擴展和擴展(不是主機應用程序)之間進行通信

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

TLDR: 是否可以在iOS App和它的Extension之間發送實時消息或通知?

我正在編寫一個iOS應用程序,其擴展名屬於同一個App Group並共享相同的CoreData(SQLite數據庫)。 我可以使用App中的CoreData讀取和寫入數據庫,並且從擴展程序中,它們共享相同的內容。

我的問題是:是否可以在應用程序和擴展程序之間發送消息或通知,以便在必要時通知對方更新?

我嘗試通過NSNotificationCenter發送通知,但這不會“超出”App / Extension,如果我嘗試寫入共享NSUserDefaults的組並聽取NSUserDefaultsDidChangeNotificationNSUserDefaultsDidChangeNotification同樣的問題。 這適用於應用程序,但擴展程序沒有收到任何東西(當我知道它已啟動並且它共享相同的NSUserDefaults )。 知道如何讓事情保持同步嗎?

TLDR: 不,但有一個黑客

iOS應用程序沒有真正的進程間通信,有或沒有擴展。 NSDistributedNotification仍然沒有從OS X到iOS,也可能不會。

使用某些擴展類型,您可以通過NSExtensionContext打開URL,並使用它們將數據傳遞到處理URL的應用程序。 這會將應用程序帶到前台,這聽起來並不像您想要的那樣。

但是,有一個hack可能會讓你得到你需要的東西。

  • 寫入應用程序組目錄中的文件,而不是寫入用戶默認值。
  • 不要直接寫文件 - 使用NSFileCoordinator對文件進行協調寫入。
  • 在想要了解文件更改的對象上實現NSFilePresenter ,並確保調用[NSFileCoordinator addFilePresenter:someObject]
  • 在文件展示器上實現可選的presentedItemDidChange方法。

如果你做這一切的權利,你可以寫從任一應用程序或擴展該文件,然后有presentedItemDidChange在另外一個被自動調用。 作為獎勵,您當然可以閱讀該文件的內容,因此您可以來回傳遞任意數據。

有關在主機應用程序和應用程序擴展之間進行通用雙向通信的替代方法,請嘗試MMWormhole

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

它是CFNotificationCenter的一個相當輕量級的包裝器,並使用“Darwin”通知進行進程間通信( IPC )。

它使用應用程序的共享容器來回傳遞有效負載,甚至封裝甚至必須自己創建文件。

該類(以及回購中的示例應用程序)似乎運行良好,並且響應很快。

我希望這也有幫助。

您可以使用黑客在iOS或應用和擴展程序中的任意兩個應用之間進行通信。 唯一的事情 - 它不適用於NetworkExtension,因為Apple阻止了其中的任何I / O.

您可以通過以下方式向DarwinNotificationCenter發布通知:

    let notificationName = CFNotificationName("com.notification.name" as CFString)
    let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()

    CFNotificationCenterPostNotification(notificationCenter, notificationName, nil, nil, false)

在你的應用中添加觀察者:

    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)

一些鏈接: 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

我一直在努力解決同樣的問題,也沒有找到一個干凈的解決方案。 解決此問題的另一種方法是簡單地在擴展中運行計時器並定期檢查共享容器首選項/數據庫中的值,然后根據需要進行更新。 不優雅,但它似乎工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM