I am trying to implement VDKQueue but only get ‘VDKQueueFileWrittenToNotification’ back as the notification regardless of the file activity in the watched folder. Deletes, file size changes all report back as this same message.
I think everything is set up OK, but maybe not…
[self.theQueueWatcher setDelegate:self];
self.theQueueWatcher.alwaysPostNotifications=YES;
[self.theQueueWatcher addPath:self.hotFolderPath notifyingAbout:VDKQueueNotifyDefault];
This is on 10.8.2.
Does anyone know if anything underlying in the OS has changed which would cause this? Or what I am missing?
After contacting the author of VDKQueue, he helpfully(seems like a nice guy) pointed out the purpose of kQueue, and therefore VDKQueue, was to watch an individual file for changes etc, not a folder as I was doing. So now starts the voyage into FSEvents which Bryan recommended was the best way to achieve this task.
Thanks Bryan.
Hope someone else finds this useful.
Related
I'm trying to troubleshoot an issue on watchOS.
I'm not sure how to reproduce the problem I'm seeing, but I do encounter it occasionally during testing on a real device in the wild, so I'm trying to use os_log in order to diagnose the problem after the fact.
As a first step, to make sure I understand how how to write to the log and access it later, I've attempted to log an event any time the app first loads.
In the ExtensionDelegate.swift file for my app, I added this:
import os.log
extension OSLog {
private static var subsystem = Bundle.main.bundleIdentifier!
static let health = OSLog(subsystem: subsystem,
category: "health")
}
Then, I updated the applicationDidBecomeActive delegate function with this:
func applicationDidBecomeActive() {
os_log("App Started",
log: OSLog.health,
type: .error)
}
I know it's not really an error message, but from what I've read, messages that are not .error are not written to saved to the log for later. I want to make sure it gets written to the log like a real error would.
I installed the sysdiagnose profile, then installed the the most recent version of my app.
After testing the app for the day, I attempted to export the file. Following the instructions I've found elsewhere, I produced a sysdiagnose on Apple Watch by holding the Digital Crown and Side button for two seconds (and felt the haptic feedback when I released).
Then, I put the watch on the charger for a few minutes per the instructions here, which recommended 15 minutes.
I opened the Watch app on my paired iPhone, then went to General > Diagnostic Logs and downloaded the sysdiagnose from Apple Watch, and sent it to my computer with AirDrop.
This gave me a tarball file (for example, sysdiagnose_2021.03.05_17-01-57-0700_Watch-OS_Watch_18S801.tar.gz). Once I decompressed that, I had a folder of lots of files and subfolders.
After poking around in this folder, I figured my best bet was to look in the system_logs.logarchive file. I opened that in the macOS Console app, set the Showing dropdown to All Messages, and looked around the time I opened the app. I didn't see any log output from my app.
I also filtered for "App Started" (the log message from my app) and didn't find anything.
Then, I filtered by category for "health" and didn't find the event I had logged.
Is system_logs.logarchive the correct place to be looking for the log output from my app?
If not, where should I be looking? Or what am I doing wrong?
I really want a better understanding of how I can log messages on Apple Watch so I can view them later so I can make my Apple Watch apps more robust, but I'm at a dead end.
Am I looking in the wrong place? Or am I setting up the logging wrong? Or is it something else? I would appreciate any guidance about this!
According to the Apple Dev Forms, sysdiagnose allows you to view the logs on your apple watch.
Does UIManagedDocument handle row level conflcts for me or do I need to handle those, and his answer was it does handle row level conflicts. Maybe I misunderstood him but I am not seeing this.
So I am going to ask a few key questions in hopes of getting some clarification here, again this is UIManagedDocument
If I have a table Author having first and last name fields what happens if:
A) I have a row with author: 'Jon Do' - it has sync'd to two devices. Then I edit the first name on one device from 'Jon' to 'John' and edit the last name on the other device from 'Do' to 'Doe'. How will iCloud and UIManagedDocument handle this? Will I get some sort of a notification that I need to respond to in order to handle the conflict? I tried the following code but I never get the notificiation:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(_ondocumentStateChangedNotification:) name:UIDocumentStateChangedNotification object:self.openedDoc];
B) What if I add a different author to the two devices so that there are now two rows to be merged will UIManagedDocument handle that for me or do I need to do something myself? If I need to do something myself what do I need to do? I tried signing up for the NSPersistentStoreDidImportUbiquitousContentChangesNotification but that doesn't ever seem to come through for me either. Which context do I sign up against? I tried this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(_onPersistentStoreDidImportUbiquitousContentChanges:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotificationobject:self.openedCaddy.managedObjectContext.parentContext];
Also do I need to handle the NSManagedObjectContextDidSaveNotification myself for a UIManagedDocument or does UIManagedDocument handle that for me?
Any and all help is greatly appreciated I am really struggling here. I adopted iCloud and UIManagedDocument at the launch of iOS 5 and fumbled my way though the lack of documentaiton then but managed to ship a product but now I want iCloud to really work not simply do a winner takes all approach to document sync.
I figured it out. UIManagedDocument does handle row level conflicts.
The reason I never saw any name:NSPersistentStoreDidImportUbiquitousContentChangesNotificationobject notifications is because I was not setting the moc's persistent store options properly. To get core data to start syncing you have to set at a minimum the following options: NSPersistentStoreUbiquitousContentNameKey & NSPersistentStoreUbiquitousContentURLKey.
When I first started using iCloud 2 years ago I always assumed that the call to setUbiquitous:itemAtURL:destinationURL:error: did this for me and was equivalent but it's not. setUbiquitous:itemAtURL:destinationURL:error: simply tells iCloud to sync the files at that URL, it does nothing with core data - think dropbox. To get the core data portion of UIManagedDocument to sync those two options need to be set.
I have started a github repo that clarifies some of this and makes getting up and running with UIManagedDocument much easier. http://github.com/dtrotzjr/APManagedDocument
Hopefully this helps someone else. I feel rather dumb not realizing this sooner but when I first implemented iCloud sync for iOS 5 2 years ago the documentation was sparse and iCloud didn't work very well so I assumed my behavior was normal.
I use NSTask to run my helper application. On 99% one my customer systems this works fine, but two got back to me letting me know it doesn't. One of them was nice enough to let me look into the issue per remote desktop.
I tried a lot of different NSPipe/NSFileHandle combination for StandardOutput/StandardError to make sure the problem is not related filling up these buffers. Example 1 and 2. My guess is that it is not related because it works fine on so many systems and _dyld_start is too early on in the application lifecycle to fill up StandardOutput/StandardError.
Other notes about the problem:
Launching the helper app from the terminal works fine.
Attaching and detaching the gdb on the stuck process and after-worth it works fine and when it finished NSTask picks up work after -waitUntilExit.
Using fork(2) and execv(3) instead of NSTask is able to launch and run the helper fine.
The parent process is sandboxed but I think previous reports where non-sandboxed on Mac OS X 10.6/10.7.
Screenshot of the process Sample from Activity Monitor:
Any clues or debugging tips to figure out why the helper is stuck in _dyld_start are welcome!
Since nobody answered, I am throwing a few ideas. Maybe one of them is the answer – only guessing – but since clues and tips are welcome, you could take a look at:
the list of the loaded libraries in the crash dump (there may be a clue there)
any error that would happen in the child process (after the fork). However, I see why it could be difficult to get back any post-fork error.
If I recall correctly, NSTask calls posix_spawn(2). This may be a clue, since using fork(2) and execv(3) seems working, you could focus on the differences between NSTask and the non-blocking alternative. Clearly, something is happening at the very beginning that prevents the child from executing properly.
Are you sure it is stuck and not crashed? As far as the user could tell, your app your app wouldn't look like it crashed. Only the child process would crash.
As a last resort, you could try to look for any Mach exception occuring (if
any, that would mean an error, which you wouldn't be able to
recover anyway. But it would provide valuable clues nonetheless).
You can tell willing custommers to send you their sysdiagnose. To this goal, ask them to hit Command + Option + Control + . + Shift to wait a few minutes. Soon after, their finder should pop a window to reveal a file named: sysdiagnose_timestamp_.tar.gz. Kindly ask them to mail it to you. Mine is around 5 MB. More details on the sysdiagnose man page.
I envisage I'll run into problems as i haven't done this before.
I'm thinking that I can either define a date at the start of the method or initialise a class.
Then at the end of the method, call the commit method, which will write the time taken about with some sort of code to determine where the measurement was made.
Since you're crashing before the app finishes launching, so no code is going to fix this. If TestFlightApp isn't working, any other code-based solutions are likely to have the same problem.
As #dasblinkenlight noted, NSLog timestamps, so that's a really easy first step. Then you need to get the logs.
If possible, have your user install and run the iPhone Configuration Utility. Have her connect her device and select it from the Devices list. Then select Console and "Save Console As..." She can then mail it to you.
Short version: I think I'm asking for a file too soon, but it's pretending like it's ready. Am I missing something?
Slightly longer version: I am writing files to disk. Before I do so, I have the user add some meta data, including the new file name. Once the user is done, the screen goes away and the program writes the file to disk. The user can then look at a list of files. That list is generated by reading the contents of a folder. The new file is in the list of files, but when I try to extract info from the file to display (e.g. file size) the program crashes. As best as I can tell, the crash occurs because, while the file is there in name, it's not available to be read. (By the way, these are small files - a few hundred k.)
First, is it possible that a file shows up in the directory but isn't all there yet?
a
And second, if so, how do I check to see if the file is ready to be read?
Thanks much.
UPDATE:
Thanks. I'll try to add more info. I'm recording an audio file with AVAudioRecorder. The init line is:
soundrecording = [[AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:&error];
The program goes through it's UI updates and metering and all that. When the audio is stopped, I call:
[soundrecording stop];
and when everything else is updated and ready to move on, I call:
[soundrecording release];
soundrecording=NULL;
As far as I understand, this should take care of releasing the file, yes?
Thanks again.
The first thing I would do is confirm that you're right about the file not being ready yet. To do that, sleep your program for a second or two after writing and before reading. A few hundred KB should not take longer than that to be ready.
If it still fails, my guess is that you haven't closed the file handle that you used to write it. It may be unready for reading because the file system thinks you might keep writing.
Usually, the way to check to see if a file is ready is to attempt to open it. If that succeeds, you can read it. Or if it fails with an error, you can handle the error gracefully:
In a command-line utility, you might print the error and quit, and the user could try again.
If it's a background program that should not quit, like a server, you could log the error. You might also try again automatically after a delay. If it's a big deal kind of error, you might want to have the program email you about it.
In an GUI window app, you probably want to show an error dialog or panel, and then give the user an opportunity to retry.
Now that you have added sample code, I can say some more.
First, the class reference seems to say that the stop method will close the file. However it also seems to suggest that there is an underlying audio session going on, and possibly some conversion. I think I recall that the iPhone's Voice Notes app, which probably uses this API, has to do some work to compress a long recording after it's completed.
So I support your hunch. I think that your file may not be closed yet, but on another thread that is processing the recorded data into a proper format to save.
You probably want to set a NSTimer to attempt to open the file every second or so, so that your user interface can perk up when it's done. You probably want to show a "Please wait" sort of message in the meantime, or otherwise let the user know it's working.