小编Nie*_*aan的帖子

如何处理有关核心数据,共享偏好和通知的Mac OS X Helper/Main应用程序架构?

我对一个正在研究的项目(Mac OS X应用程序)有一些架构上的怀疑.它基本上由两个元素组成:一个在后台运行的守护进程收集一些数据,一个查看器用于表示收集的数据.

守护程序应在状态栏中显示(无停靠图标),并包含可通过状态栏访问的小菜单.它将数据保存在核心数据存储中.其中一个菜单项是打开查看器链接.打开此查看器时,正常的 GUI应用程序应该开始包括停靠图标和菜单栏.打开应用程序本身时也会打开查看器(通过双击图标).

经过一些实验,我发现实现这个功能的最好方法是创建两个应用程序,代表查看器的主应用程序和代表守护进程的辅助工具.我这样做的原因之一是不能LSUIElement立即在值之间切换以强制守护进程/查看器状态.

现在我对这个架构有一些疑问:

  • 守护程序和查看器应用程序都使用相同的核心数据存储来保存和检索数据.拥有多线程应用程序时,我知道NSManagedObjectContext需要多个对象才能正确同步数据.如何让多个应用程序同时使用相同的核心数据存储?这是否可能没有冲突,锁定等风险?我如何保证一致性?

  • 守护程序应始终在查看器启动时启动.我通过简单地遍历所有打开的进程并检查是否列出了守护进程的bundle标识符来实现这一点.如果没有,守护进程使用NSWorkspace's' 开始launchApplication.这很好用.现在,当用户退出守护程序时,查看器也应该停止.查看器通知守护程序停止的最佳方法是什么?如果守护程序消失,我可以定期检查活动进程并退出查看器但听起来有点奇怪.我希望选择某种通知,当观众即将关闭时,我会发送这些通知.但由于应在应用程序之间发送和捕获此通知,因此我不知道哪种简单通知服务可用.有什么想法吗?

  • 该应用程序是沙盒,因为它将在Mac App Store上分发.使用NSWorkspace's 启动应用程序launchApplication会导致目标应用程序在与我认为根本不是问题的源相同的沙盒环境中运行,因为在同一个沙箱中运行这两个应用程序感觉更好,可能是.但想象一下这个场景:守护进程在登录时自动启动(使用SMLoginItemSetEnabled),用户双击Viewer.app.由于守护程序已在运行(再次通过循环执行活动进程来检查),它将无法启动.现在我们有守护进程和查看器在不同的沙箱中运行吗?这会导致偏好,核心数据存储等问题吗?

  • 我想NSUserDefaults用于基本配置,我可以以某种方式在守护进程和查看器之间交换这些数据吗?同样,两个应用程序将具有不同的包标识符.

在此先感谢您的帮助,谢谢!

macos notifications daemon core-data helpers

48
推荐指数
1
解决办法
968
查看次数

Sandboxed Mac应用程序并不总是使用SMLoginItemSetEnabled()自动启动

我正在开发的沙盒Mac应用程序有一个非常奇怪的问题.一个要求是用户应该有可能在系统启动时启动应用程序.为此,我正在使用http://blog.timschroeder.net/2012/07/03/the-launch-at-login-sandbox-project/中描述的SMLoginItemSetEnabled().

当用户第一次启动应用程序并启用此选项时,我可以看到使用launchctl列表将一个条目添加到launchctl.当我重新启动系统时,应用程序未启动.更奇怪的是,使用launchctl列表找到的条目已经消失.但是,在/private/var/db/launchd.db/com.apple.launchd.peruser.501/overrides.plist中仍然可以使用类似的条目,其中键为Disabled,为false.

当我手动启动应用程序并再次将选项设置为自动启动时,该条目在launchctl列表中再次可用.当我重新启动系统时,应用程序将自动启动.总结,由于某种原因,SMLoginItemSetEnabled()仅在我第二次运行应用程序时才起作用.因此,它看起来类似于这个问题:https://stackoverflow.com/questions/16354295/sandbox-app-with-loginitems-only-work-after-second-app-launch.但是,没有提供解决方案.

/sf/ask/1144800681/

macos cocoa

11
推荐指数
1
解决办法
1727
查看次数

Mavericks和NSStatusItem的自定义视图,带有多个监视器

由于小牛每个屏幕都有自己的状态栏.这也意味着在状态栏中运行的应用程序(使用NSStatusItem)理论上有多个NSStatusItem对象关联.实际上,虽然用户可能会看到NSStatusItem的多个"实例",但它只是一个(我已经测试过了).现在,当您在状态图标中使用自定义视图时会出现以下问题:当用户单击状态图标时,我使用drawStatusBarBackgroundInRect方法以编程方式"突出显示"它.问题是状态图标的每个"实例"(每个屏幕一个)都会突出显示,尽管用户只是点击了一个.此行为与没有自定义视图的状态图标不同.有没有办法正确实现这个?

举个好例子,只需在使用多个显示器时点击Dropbox状态图标即可.你会注意到在另一个屏幕上选择了图标.

macos cocoa nsstatusitem nsstatusbar osx-mavericks

8
推荐指数
2
解决办法
1193
查看次数

在(自动)续订订阅后,本地收据不会更新

我有一个使用应用内购买(IAP)的应用程序,特别是可自动更新的订阅.

有时似乎,当订阅自动续订时,本地收据不会自动更新.因此,在本地检查活动订阅是否可用会导致错误.远程执行相同的验证(使用Apple服务器)返回true.

如何以及何时更新本地存储的收据,或者这是否只能手动触发?如果是这样,是否需要使用SKReceiptRefreshRequestSKPaymentQueue的restoreCompletedTransactions进行此操作?基于Apple的文档,前者似乎是要走的路:

刷新收据的请求,表示用户与您的应用程序的交易.

不幸的是,这失败了,也许是因为它认为有更新?但是有:因为本地收据已过时,因为它不包含续订的订阅状态.

我想确保我正确地做事并且这种行为(偶尔会再次发生)并不是Apple的结果.

感谢您的任何反馈.

macos cocoa storekit in-app-purchase auto-renewing

6
推荐指数
0
解决办法
136
查看次数

NSPersistentCloudKitContainer 将 NSManagedObject 子类恢复为历史值

我有一个用于NSPersistentCloudKitContainer与 iCloud 同步数据的应用程序。用户报告偶尔数据丢失,之后我开始调试我的实现。

我的应用程序实现的一部分是显示一个弹出窗口,其中显示信息并有一个确认按钮。当用户单击此按钮时,自定义NSManagedObject子类的一个或多个实例将被修改。

同时,NSPersistentCloudKitContainer在应用程序退出并激活时触发镜像过程。当用户单击上述确认按钮时会发生这种情况。它通过执行NSCloudKitMirroringExportRequestNSCloudKitMirroringImportRequest请求来做到这一点。

换句话说,在我的应用程序中,数据同时被修改(通过代码显式)和镜像(通过 CloudKit 隐式),这就是出错的地方。

本质上是这样的:

  1. 子类NSTimeInterval实例的属性 ( )NSManagedObject增加(例如 0 + 1 = 1)。
  2. NSPersistentCloudKitContainer 当应用程序激活或退出时隐式开始镜像数据。
  3. 在此过程中但在完成之前,该属性再次增加(例如 1 + 1 = 2)。
  4. 在内部,镜像过程完成。

在这个阶段,我希望属性的值与最新的(本地)更改相匹配(因此在我的示例 2 中)。但相反,它匹配初始增量(因此在我的示例 1 中),覆盖我最新的(本地)更改导致数据丢失。显然,NSCloudKitMirroringImportRequest恢复到镜像进程启动时的状态,这也可以在日志中看到:

CoreData: debug: CoreData+CloudKit: -[PFCloudKitImporterZoneChangedWorkItem applyAccumulatedChanges:error:]
[…]
Importing updated records:
(
    "<CKRecord: 0x10225b560; recordID=5458F9C8-7BE2-4563-92DE-650ED4C643F5:(com.apple.coredata.cloudkit.zone:__defaultOwner__), recordChangeTag=23, values={\n    \"CD_activity\" = \"3E497A4C-6467-48F4-B7F4-6F1B2B7BC779\";\n    \"CD_date\" = \"2020-04-26 07:28:00 +0000\";\n    \"CD_duration\" = \"1\";\n    \"CD_entityName\" = Mutation;\n}, recordType=CD_Mutation>"
)
Run Code Online (Sandbox Code Playgroud)

在这个阶段,我不确定这是否是NSPersistentCloudKitContainer …

macos nsmanagedobject swift cloudkit nspersistentcloudkitcontainer

6
推荐指数
0
解决办法
214
查看次数

NSPredicate转义反斜杠字符

我有以下代码:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like[c] %@", projectName];
[fetchRequest setPredicate:predicate];
[moc executeFetchRequest:request error:error]; // moc & error are defined elsewhere
Run Code Online (Sandbox Code Playgroud)

当我在projectName为“ asdf”的情况下运行此代码时,一切正常。但是,当将该值设置为“ asdf \”(注意最后的反斜杠)时,将出现以下异常:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The backslash is a wildcard char, and cannot appear unescaped at the end of a string.'
Run Code Online (Sandbox Code Playgroud)

po请求向我提供了以下信息:

po request
<NSFetchRequest: 0x101348ee0> (entity: Project; predicate: (name LIKE[c] "asdf\\"); sortDescriptors: ((null)); type: NSManagedObjectResultType; )
Run Code Online (Sandbox Code Playgroud)

在我看来这是一个简单的问题,但无法在Internet上找到解决方案,谁知道呢?

macos cocoa core-data objective-c nspredicate

2
推荐指数
1
解决办法
1435
查看次数