Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在包含扩展和扩展的iOS应用程序(非主机应用程序)之间通信_Ios_Core Data_Swift_Nsnotificationcenter_Ios Extensions - Fatal编程技术网

如何在包含扩展和扩展的iOS应用程序(非主机应用程序)之间通信

如何在包含扩展和扩展的iOS应用程序(非主机应用程序)之间通信,ios,core-data,swift,nsnotificationcenter,ios-extensions,Ios,Core Data,Swift,Nsnotificationcenter,Ios Extensions,TLDR:是否可以在iOS应用程序及其扩展之间发送实时消息或通知 我正在编写一个iOS应用程序,其扩展属于同一个应用程序组,并共享相同的CoreData(SQLite数据库)。我可以使用应用程序和扩展程序中的CoreData读取和写入数据库,它们共享相同的内容 我的问题是:是否可以在应用程序和扩展程序之间发送消息或通知,以通知另一方在必要时进行更新 我尝试通过NSNotificationCenter发送通知,但这不会“退出”应用程序/扩展,如果我尝试写入共享NSUserDefaults组并收听n

TLDR:是否可以在iOS应用程序及其扩展之间发送实时消息或通知

我正在编写一个iOS应用程序,其扩展属于同一个
应用程序组
,并共享相同的CoreData(SQLite数据库)。我可以使用应用程序和扩展程序中的CoreData读取和写入数据库,它们共享相同的内容

我的问题是:是否可以在应用程序和扩展程序之间发送消息或通知,以通知另一方在必要时进行更新

我尝试通过
NSNotificationCenter
发送通知,但这不会“退出”应用程序/扩展,如果我尝试写入共享
NSUserDefaults
组并收听
nsUserDefaultsIDChangeNotification
,也会出现同样的问题。这在应用程序内部工作,但扩展程序没有接收任何内容(当我知道它已启动并且共享相同的
NSUserDefaults
)。知道如何保持同步吗?

TLDR:不知道,但有一种方法

无论是否有扩展,iOS应用程序都没有真正的进程间通信
NSDistributedNotification
仍然没有完成从OSX到iOS的旅程,而且可能不会

对于某些扩展类型,您可以通过
NSExtensionContext
打开URL,并使用它们将数据传递给处理URL的应用程序。这会使应用程序出现在前台,这听起来不像你想要的

不过,有一种黑客可能会满足你的需要

  • 写入应用程序组目录中的文件,而不是写入用户默认值
  • 不要直接写入文件——使用
    NSFileCoordinator
    对文件执行协调的写入
  • 在希望了解文件更改的对象上实现
    NSFilePresenter
    ,并确保调用
    [NSFileCoordinator addFilePresenter:someObject]
  • 在文件演示器上实现可选的
    presentedItemDidChange
    方法

如果所有这些操作都正确,则可以从应用程序或扩展名写入此文件,然后在另一个应用程序或扩展名中自动调用
PresentedItemChange
。作为奖励,您当然可以读取该文件的内容,这样您就可以来回传递任意数据。

我一直在努力解决同一问题,也没有找到一个干净的解决方案。解决这个问题的另一种方法是在扩展中运行一个计时器,定期检查共享容器首选项/数据库中的值,然后根据需要进行更新。虽然不优雅,但似乎很管用

要获得在主机应用程序和应用程序扩展程序之间进行通用双向通信的替代方法,请尝试MMWormhole

它是围绕CFNotificationCenter的一个相当轻量级的包装器,使用“Darwin”通知进行进程间通信()

它使用应用程序的共享容器来回传递有效负载,甚至封装了自己创建的文件

该类(以及回购协议中的示例应用程序)似乎运行良好,并且响应速度相当快


我希望这也能有所帮助。

有一种黑客可以用来在iOS或app and extension中的任意两个应用程序之间进行通信。唯一的问题是,它不能与NetworkExtension一起工作,因为苹果正在阻止其中的任何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)
一些链接:


我试图用open()+一些标志来观察文件系统的更改,但没有成功。我不知道NSFilePresenter!这非常有效,谢谢!Ludovic Landry,请举一个例子,说明你是如何成功地实现沟通的?谢谢,如果包含我的应用程序未运行(已终止),是否会启动/唤醒包含我的应用程序?如果应用程序未运行,则不会收到通知。不过,你的应用程序在启动时需要加载文件内容,因此它不需要通知来查找最新数据。好吧,只是一个警告-你不能在回调中访问“self”。有一种方法可以使用void指针来访问它,但这种方法也不能很好地工作,会出现“EXC_BAD_access”错误,这些错误根本无法捕获和处理(尽管可以这样做:)。不过,您可以访问的是类本身,也就是说,您可以将类的实例存储为静态变量,从中可以调用方法。建议您首先检查实例是否存在。另外,这个类将不能deinit(),因为它的引用仍然硬绑定到静态变量中,所以它在内存中是活动的。只有当您覆盖/取消该静态实例变量或phone内存不足并开始从左到右清除时,它才会被取消初始化。您可以在回调中发布NotificationCenter,然后在应用程序中的任何位置添加观察者,而不是尝试访问“self”。对我有效:)我试过了,但当应用程序在后台时它不起作用。我在应用程序上发布了一条来自iOS 14小部件扩展的通知。当我在前台打开应用程序时,通知已经发出,但不是在之前。我认为它可以与背景模式一起工作。另请参见文档: