I have an iOS app and macOS app that sync data using CloudKit (no CoreData involved). Syncing mostly works, except that on my development machine I don't get any push notifications when other devices make changes.
For example I can make a data change on macOS and it gets pushed to my iOS app immediately, however if I make a change on iOS, the macOS app never gets a notification. I can check in CloudKit dashboard and the data has been updated, and a push was sent, but the macOS app never gets it.
The subscription is set up like so (same code on macOS and iOS) and it reports success on both platforms:
private func subscribeToCloudKitChanges() {
		if UserDefaults.standard.bool(forKey: ckSubscriptionStateKey) == true { return }
		
		let subscription = CKDatabaseSubscription(subscriptionID: cloudKitPrivateChangeID)
		let notificationInfo = CKSubscription.NotificationInfo()
		notificationInfo.shouldSendContentAvailable = true
		subscription.notificationInfo = notificationInfo
		
		let op = CKModifySubscriptionsOperation(
				subscriptionsToSave: [subscription],
				subscriptionIDsToDelete: []
		)
		op.modifySubscriptionsCompletionBlock = { (_, _, error) in
				if let error = error {
						logger.error("Error setting up CloudKit subscriptions: \(error.localizedDescription)")
						UserDefaults.standard.set(false, forKey: ckSubscriptionStateKey)
				} else {
						logger.log("CloudKit subscriptions created")
						UserDefaults.standard.set(true, forKey: ckSubscriptionStateKey)
				}
		}
		op.qualityOfService = .utility
		ckContainer.privateCloudDatabase.add(op)
}
The remote notifications are requested like so, and always reports that is is registered. Though oddly enough I never get the callback to say it has been registered?
func applicationDidFinishLaunching(_ notification: Notification) {
		NSApplication.shared.registerForRemoteNotifications()
		print("Requested remote notifications. Status: \(NSApplication.shared.isRegisteredForRemoteNotifications)")
//...
And finally, to receive the iCloud change notification:
func application(_ application: NSApplication, didReceiveRemoteNotification userInfo: [String : Any]) {
guard let ckn = CKDatabaseNotification(fromRemoteNotificationDictionary: userInfo) else { return }
if ckn.subscriptionID == cloudKitPrivateChangeID {
DispatchQueue.main.async {
self.cloudKitPrivateDBChanges.send(ckn)
}
}
}
Post
Replies
Boosts
Views
Activity
According to the HIG, - https://developer.apple.com/design/human-interface-guidelines/macos/windows-and-views/popovers/ changes in popover size should be animated:
Animate changes in size to avoid giving the impression that a new popover replaced the old one. How can this be done in SwiftUI? No matter where I put .animate() annotations, I can't get the actual popover frame to transition smoothly. Best I can get is that the popover frame changes immediately, and then the controls awkwardly animate over to the right location.
I have a macOS daemon that needs to store a password. If I run the daemon as root, I can store and retrieve the password in the system keychain, but if I create a dedicated user/group for the daemon (so it runs as user _myDaemon for example), adding the password to the keychain fails with -61 (errSecWrPerm).
My daemon will be responding to network requests so I would prefer it to not run as root for security reasons. I'm not sure what is the best way to proceed:
Is there a way to grant system keychain access for a dedicated daemon user?
Should I split off the keychain access into a "helper daemon" that runs as root?
Something else?
I have a local file server with git repositories and ssh access. I have several swift packages stored there, and some of them have been successfully added as dependencies in projects using Xcode 11.
I am now unable to add any package dependencies like this in Xcode 12.
I can successfully clone the repo from the Source Control -> Clone... menu so I know the repo is valid.
The steps I am following are to add the dependency:
File -> Swift Packages -> Add Package Dependency...
Enter: ssh://MyServer.local/path/to/git/repo
Xcode prompts for credentials -> success
Xcode asks for the import rules, with correctly filled in version numbers (so I know it can access the repo at this point)
I accept the defaults, click "next"
I get the following error:
The source control operation failed because no working copy could be found. Make sure the file is in a valid working copy and try again. Any idea how resolve this? Existing SPM packages resolve and work correctly, but I can't add any new ones.
I am creating DispatchIO channels using the file descriptor constructor:self.channel = DispatchIO(type: .random, fileDescriptor: self.file, queue: fileProcessingQueue, cleanupHandler: { (errorCode) in
// clean up when the channel closes
})The documentation for cleanupHandler states:"The handler to execute once the channel is closed."The better documentation (when you switch language to ObjC) states:"The block to enqueue when the system relinquishes control of the channel’s file descriptor.""... the system takes control of the specified file descriptor until one of the following occurs:You close the channel by calling the dispatch_io_close function.
..."So from both of these, I expect the handler gets enqueued and executed if I callself.channel.close(flags [.stop])But it seems to never get executed under this condition. In fact, it's very difficult to get the cleanup handler to be called at all. The only way so far I have been able to get it to execute is by calling close() on the underlying file descriptor. Am I doing something wrong here? There's cleanup that I want to do when the channel closes that is different than the cleanup I want to do when I'm done with the file descriptor. Is this not the correct place to do it?
Am I mis-using a concurrent queue in the following scenario?Situation:My app needs to process files submitted by the user. These files will usually be in batches of 10's or 100's of files, which may have arbitrary dependencies between files (i.e. file "y.txt" must be processed before file "x.txt" can finish processing). The processing of each file can take up to a few seconds. In general, it is not possible to determine ahead of time what the dependency graph looks like. I have to start processing a file, and somewhere in the middle I may hit a reference to another file, at which point I need to wait for the other file to finish processing before continuing to process this file.My Approach:What I tried to do is just submit all the files as individual `DispatchWorkItem`s (one file per work item) to a concurrent queue. When I determine that a particular file (call it "x.txt") is dependent on another file (y.txt), I look up the DispatchWorkItem for y.txt, and call DispatchWorkItem.notify(...) with a closure that will get me the processed result of y.txt, then I DispatchWorkItem.wait() for that result within x.txt's work item before continuing to process x.txt. This works great if there are only a few files.The problem:If there are a lot of files (say 100+), with many of the files dependent on one particular file in the batch, what seems to happen is GCD will enqueue Work item 1, it will eventually wait on a dependency, GCD spawns a new thread for work item 2, then it waits on a dependency, ... all the way up to 64 work items in flight, all waiting on a dependency. Then GCD just stops. If the dependency they are all waiting on hasn't been started yet, the app is hung.Is there a better way to do this? Is there some internal limit of 64 blocked threads in a single queue?
I have some old network code that I am porting to Network.framework. The code is ported over easily, however I am struggling to get the tests ported. My old code accepted posix sockets from accept() and passed them off to handler objects. In the tests, I would instead create a pre-connected pipe with socketpair() and pass one of sockets off to a handler object and drive the other socket from my test.In my new code, the handler objects are normally passed an NWConnection, but for testing I don't see a way to create both ends of the pipe.How can I create two NWConnection objects that are connected to eachother?
Prior to Mac OS X 10.12.2 I had been using the code below to generate ridge noise the looked more or less like the picture in the documentation for GKRidgeNoiseSource:let srcRidges = GKRidgedNoiseSource(frequency: 0.1,
octaveCount: 2,
lacunarity: 1.5,
seed: 12345)
let noise = GKNoise(srcRidges)
let map = GKNoiseMap(noise,
size: vector_double2(x:200, y: 200),
origin: vector_double2(x:0, y:0),
sampleCount: vector_int2(x:200, y:200),
seamless: false)
let tex = SKTexture(noiseMap: map)
let cgimg = tex.cgImage()
let nsimg = NSImage(cgImage: cgimg, size: NSSize(width: 200, height: 200))The same code after 10.12.2 produces mostly garbage, as can be seen by pasting this into a playground. Am I using it wrong, or did something break with this noise source?