fetchRemindersMatchingPredicate not retrieving new data - eventkit

I've been using EventKit for years in my app (since macOS 10.10) but it's having an odd problem in Mojave.
Previously once I received an EKEventStoreChangedNotification I could query for changed reminders with this:
NSPredicate *predicate = [self.eventStore predicateForRemindersInCalendars:#[self.taskCalendar]];
[self.eventStore fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) {
self.allFetchedTasks = reminders;
}];
Worked like champ. Setting a breakpoint within that block, I could switch to Reminders, change the task title, instantly pop back in the debugger and the reminders array would have the change (via "po [reminders.firstObject title]").
However, now in Mojave the fetch appears to return old information. I get thrown back in the debugger as soon as I change the task title in Reminders but the reminders array still contains the old info. That is, [reminders.firstObject title] is still showing the original title not the title as it exists currently in Reminders. I can continue to change the title in Reminders and each time I'm brought back into the debugger and I still see the original title.
I also attempted to use calendarItemsWithExternalIdentifier but it also returns the original value.
If I relaunch my app then it grabs the latest info but, again, subsequent fetches due to change notifications return the original value.
It doesn't look like Mojave's EventKit has any new caching I can control. Is there something else I'm missing? Do I need to reconstruct my self.eventStore each time now?

This has been fixed in Apple's macOS 10.14.4 Beta 3 release.

Related

Xcode Swift 5 MacOs app empty window when archived but works when running it from Xcode

I am building an app for Mac which logs into a website based on login and password collected from textfield and secure text field, then app opens an url which is created in my app based on date range selection with use of two date picker cell calendars. Next app displays html data in webWiev (using WKWebView), converts html to string using extension NSAttributedString and then saves retrieved data as txt file. Everything works as expected as long as app is run from Xcode "play" button. Problem is if I archive this app and launch it, it will bring up an empty window without any button, calendar or textfield. There are no errors, no crash logs on organizer, nothing.
I decided to perform a little test. I build another view controller with only one button which upon clicking will show my app main view controller. After archiving this modified app and running it outside of Xcode a window shows view controller with one button which is correct. But after clicking it nothing happens. App works great if running "inside" Xcode, a pushbutton shows main ViewController correctly. Do You have any clue what can be wrong? thank You!
Edit 1. So I found a discussion on apple which mention this problem. It is associated with IB WKWebView and problem is already known since some time. Now I have to get around the problem. Apple forum link: https://forums.developer.apple.com/thread/116047
Did you embed WebKit.framework to your app?
After comment that I wrote, I founded a solution and solved with this method.
Please check it out.

all UISteppers in my iOS app have become disabled

My app uses UIStepper controls in a few different views. I released a minor update to the app that shouldn't affect these views at all, and I started getting reports that all the UISteppers in the app are now disabled. One user sent a screen shot, and the stepper control appears as if its enabled property were set to NO. However, there's no place in my code where I set this property at all, and the default is YES. I've searched my app for instances of the term "enabled" to make sure I'm not somehow disabling it accidentally, and I'm not.
I thought perhaps the default value for the enabled property changed between iOS versions, but the users who have reported this are running iOS 5.1.1, the same as my development devices. And I only started hearing about the problem with this app update.
Besides setting the enabled property, I found that the steppers will be disabled if the min and max values are set to the same value. I'm pretty sure this is not happening in my app. The values are hard-coded and passed to a setup method, and I haven't changed this code since many app versions ago.
Do you know any other reason why this would happen? I can't reproduce the problem myself, and it only affects some users, so it's difficult to troubleshoot.
Here's my code for creating the UISteppers, for what it's worth:
- (UIStepper *)makeStepperInput:(float )currentValue minValue:(float)minValue maxValue:(float)maxValue increment:(float)increment {
int stepperWidth = 94;
int stepperHeight = 27;
CGRect stepperFrame = CGRectMake(0, 0, stepperWidth, stepperHeight);
UIStepper *stepperInput = [[[UIStepper alloc] initWithFrame:stepperFrame] autorelease];
stepperInput.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[stepperInput setValue:currentValue];
[stepperInput setMinimumValue:minValue];
[stepperInput setMaximumValue:maxValue];
[stepperInput setStepValue:stepValue];
[stepperInput setContinuous:NO];
NSLog(#"making stepper with values %f, %f, %f, %f (%i)", currentValue, minValue, maxValue, stepValue, stepperInput.enabled);
[stepperInput addTarget:self action:#selector(onChange:) forControlEvents:UIControlEventValueChanged];
return stepperInput;
}
UPDATE: I have a user who was willing to install a debug version with the NSLog line above. He sent me the console output and it shows that the min and max value of the stepper are correct (1 and 20 in one case) and that the enabled property is YES. Unfortunately, that eliminates both of my theories about what could be happening here...
Okay, here's what happened. The method posted above is a simplified version of my real method, which provides some branching for pre-iOS 5 devices. To help with pre-iOS 5 support, I was actually declaring stepperInput as a UIControl, and then returning something different on iOS versions that don't support UIStepper.
Now the interesting part. I rolled my project back and started looking at my build settings, and remembered that before my last release, Xcode gave me one of those alert messages about my build settings being out of date. I had clicked the button to allow Xcode to make all the recommended changes. This time, I performed one change at a time and tested my app after each change.
The first of the recommended changes was to "Upgrade Compiler configuration to LVVM". ("The compiler configuration is set to 'com.apple.compilers.llvmgcc42'. This will upgrade to 'Apple LLVM compiler 4.0', which is the recommended setting for iOS targets.") As soon as I made that change, the problem appeared on my test device. So it seems that the old compiler allowed me to set UIStepper properties on an object declared as a UIControl, while the new compiler did not. Indeed, when I changed my NSLog line above to output the actual values of the stepper, instead of the values passed into the method, they all returned 0. Having its min and max values both set to 0 is what made the stepper appear to be disabled.
I didn't think this affected all users because I couldn't reproduce it, but I was testing with the older build settings rather than the build settings used for the release. So now I'm thinking that this probably does affect all users, and only some users have noticed it.
Anyway, the solution is to reorganize my code so I can declare that UIStepper as a real UIStepper, since the newer compiler doesn't allow the kind of fudging I was doing before.

Photomania- Stanford Paul Hegarty's class

is there something wrong with core data for xcode 4.3.2
I'm following the Stanford Paul Hegarty class for ios 5.0
doing the core data walkthrough (Video 14 Core data demo)
I downloaded the file here
I ran it in xcode 4.3.2 but the core data doesn't seem to work because the entries in the tableview do not appear.
I tried to run it in another computer with xcode 4.2 and ios 5.0
it's working perfectly
anybody who encountered the same problem? I'm pretty sure that xcode is at fault.
Interesting. I am having the same problems and I am also using XCode 4.3, but just thought it was because of the Flickr license that you need and which I don't have. (In FlickAPIKey.h, there is a #define FlickrAPIKey #"" and you won't download anything if you don't have that key.)
Update: I got myself a Flickr API key (you can just get one from their website) and tried the Photomania App on XCode 4.3: it works like a charm, so it looks like XCode is not your problem here. (Although on occasion I found that I had to stop and restart XCode to get rid of a strange bug or compiler error.) Anyway, maybe it is an idea to delete the data first before you try again: Just delete the App before you run it and the database file will get deleted as well.
Paul Hegarty after his class, has published an update version of his code which have a call to SAVE the CoreData database! This may be the reason why your CoreData informations doesn't persist.
His update note was:
// should probably saveToURL:forSaveOperation:(UIDocumentSaveForOverwriting)completionHandler: here!
// we could decide to rely on UIManagedDocument's autosaving, but explicit saving would be better
// because if we quit the app before autosave happens, then it'll come up blank next time we run
// this is what it would look like (ADDED AFTER LECTURE) ...
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
So, you have to Add the 'document saveToURL' line in the 'fetchFlickrDataInDocument' function like this:
- (void)fetchFlickrDataIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchQ = dispatch_queue_create("Flickr fetcher", NULL);
dispatch_async(fetchQ, ^{
NSArray *photos = [FlickrFetcher recentGeoreferencedPhotos];
[document.managedObjectContext performBlock:^{
// perform in the NSMOC's safe thread (main thread)
for (NSDictionary *flickrInfo in photos) {
[Photo photoWithFlickrInfo:flickrInfo inManagedObjectContext:document.managedObjectContext];
// table will automatically update due to NSFetchedResultsController's observing of the NSMOC
}
// should probably saveToURL:forSaveOperation:(UIDocumentSaveForOverwriting)completionHandler: here!
// we could decide to rely on UIManagedDocument's autosaving, but explicit saving would be better
// because if we quit the app before autosave happens, then it'll come up blank next time we run
// this is what it would look like (ADDED AFTER LECTURE) ...
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
// note that we don't do anything in the completion handler this time
}];
});
}
If someone is still facing the same issue using Objective-C, there is one more thing you need to do after getting API key: change all http:// to https:// within files in FlickrFetcher folder. This worked for me.

Why the applicationIconBadgeNumber is not getting deleted with appliccation ? Where it stored actually? [duplicate]

I'm setting my applicationIconBadgeNumber using this code:
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:theIntToDisplay];
The problem is that when I delete the app from an iPad and reinstall it, the app icon still shows the previous badge number. Is this default iOS behavior or can we reset it?
I found one similar question on at Why the applicationIconBadgeNumber is not getting deleted with appliccation ? Where it stored actually?, but it didn't answer my question.
This is an expected behavior, the badge number remains for a short period after uninstall e.g for the case of an immediate re-install.
Of course you can nullify badge number after every launching the application in application:didFinishLaunchingWithOptions: method but I think it is not the case because you want badge number not to be shown right after you install app and not yet launch it. In such a case just wait after removing the application and the badge numbers cache will be cleared by iOS and then install the app again. Unfortunately without jailbreaking the device there is no way to manage badge numbers behavior manually
In your app delegate under:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
Insert:
application.applicationIconBadgeNumber = 0;

NSFetchedResultsController crashing on performFetch: when using a cache

I make use of NSFetchedResultsController to display a bunch of objects, which are sectioned using dates. On a fresh install, it all works perfectly and the objects are displayed in the table view. However, it seems that when the app is relaunched I get a crash. I specify a cache when initialising the NSFetchedResultsController, and when I don't it works perfectly.
Here is how I create my NSFetchedResultsController:
- (NSFetchedResultsController *)results {
// If we are not nil, stop here
if (results != nil)
return results;
// Create the fetch request, entity and sort descriptors
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Event" inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"utc_start" ascending:YES];
NSArray *descriptors = [[NSArray alloc] initWithObjects:descriptor, nil];
// Set properties on the fetch
[fetch setEntity:entity];
[fetch setSortDescriptors:descriptors];
// Create a fresh fetched results controller
NSFetchedResultsController *fetched = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"day" cacheName:#"Events"];
fetched.delegate = self;
self.results = fetched;
// Release objects and return our controller
[fetched release];
[fetch release];
[descriptor release];
[descriptors release];
return results;
}
These are the messages I get when the app crashes:
FATAL ERROR: The persistent cache of section information does not match the current configuration. You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'FATAL ERROR: The persistent cache of section information does not match the current configuration. You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:'
I really have no clue as to why it's saying that, as I don't believe I'm doing anything special that would cause this. The only potential issue is the section header (day), which I construct like this when creating a new object:
// Set the new format
[formatter setDateFormat:#"dd MMMM"];
// Set the day of the event
[event setValue:[formatter stringFromDate:[event valueForKey:#"utc_start"]] forKey:#"day"];
Like I mentioned, all of this works fine if there is no cache involved. Any help appreciated!
I had a similar problem with one of my apps, when the Apple released the new iOS 4.0.
Search:
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
And set the value of the parameter cacheName to nil. It worked for me, hope it will for you. Let me know.
I started getting the same error when I upgraded by MacBook Pro to Snow Leopard 10.6.4 and the latest SDK.
As it turns out, many of us had been using code that wasn't in conformance with the rules, but we didn't know it because CoreData wasn't really behaving in accordance with its own rules.
Specifically, when you fetch things, they get cached, and in 4.0, that cache isn't automatically purged in cases where it was purged in the earlier SDK.
For me, the solution was simple. I just employed the class method that purges the caches. You can specify an individual entity, but I specify nil so it just does them all in this particular piece of start-up code:
[NSFetchedResultsController deleteCacheWithName:nil];
Suddenly, the little app I've worked on only to familiarize myself with CoreData is working again.
Straight from the documentation for NSFetchedResultsController:
Modifying the Fetch Request
You cannot simply change the fetch request
to modify the results. If you want to change the fetch request, you
must:
If you are using a cache, delete it (using deleteCacheWithName:).
Typically you should not use a cache if you are changing the fetch
request.
Change the fetch request.
Invoke performFetch:.
I encountered a similar problem.
When I inspected the Debugger Console, it showed what the cached objects and the fetched objects were so that I could figure out why they are inconsistent.
In my case it was due to a different predicate.
Since the values in my predicate are not dynamic, I could specify a different cache name for each predicate. That will create a cache for each 'type' I specify.
I suppose you will have to assess your need to have the cache. To specify nil, means that a fetch is made in every call.
I figured out that the error occurs only when the fetch request have some changes. If you are creating a new NSFetchRequest OR changing the predicate OR sort descriptor, then you should delete the cache or use a different cache. Otherwise, ensure that you have the same NSFetchRequest or make sure that your NSFetchedResultsController is retained and that should solve your problem.
If you're using the simulator, try resetting it--I'd guess you've changed your entity map and it's getting confused by a leftover cache. If not, you could try doing what the error says:
- (void)applicationWillTerminate:(UIApplication *)application {
[NSFetchedResultsController deleteCacheNamed:#"Events"];
//etc
}
The exception still occurs with Xcode 7 (beta 4):
You have illegally mutated the NSFetchedResultsController's fetch
request, its predicate, or its sort descriptor without either
disabling caching or using +deleteCacheWithName:
NOTE: This is with an unmodified Xcode "Template" Master-Detail iOS app with standard Xcode CoreData "boiler-plate" code created with Xcode 7 and using the latest (iOS 9) deployment target.
I noticed it first when I restarted my app in the simulator. I had been starting and stopping the app several times via Xcode and then it happened; and it kept happening. I decided to do some experiments, and the results:
Every time I stopped the app in the simulator, I would get the exception on a subsequent launch.
Every time I stopped the app using the simulator's Home button, I was able to launch it again successfully.
The issue can still be fixed as follows, using one or the other of the following methods:
In the AppDelegate's application didFinishLaunchingWithOptions method, add the following Swift NSFetchedResultsController.deleteCacheWithName(nil) or Objective-C [NSFetchedResultsController deleteCacheWithName:nil]; code. This clears out the corrupted cache.
In the Simulator, from the Simulator menu, select Reset Content and Settings. This fixes the problem, but you lose your test data.
I also believe that this is an artifact of running via Xcode and stopping the app prior to it being able to clean up. I've not seen this in the actual device.
Are you quitting the Simulator using the home button or by terminating the app in Xcode? Maybe the app isn't getting time to finish writing to the cache. Try using the home button to quit the app.
How many classes implement the same - (NSFetchedResultsController *)results method, do you use a different cache for each one? I was having the same issue and I think I fix it by using a different cache name fore some clases since I have different NSPredicates.
I was having the same problem. To fix, I put the [NSFetchedResultsController deleteCacheWithName:#"cacheName"]; before the init of resultsController. Works for me as he only goes there on the first time.
For those who run into the same problem nowadays, the problem is that somehow Core Data doesn't clean the cache so work fine at first time but doesn't after that. Then just put this line right after init the NSFetchRequest
[NSFetchedResultsController deleteCacheWithName:#"Name"];
I found via the Ray Wenderlich forums that
Note that it only crashes when the fetch request is not created yet when you add something new to the datastore, i.e. when the Locations view isn't loaded yet. If the view is loaded already, then it works fine. Odd, eh?
So, what happened in my case was this:
The normal launch process entails constructing an NSFetchedResultsController.
Because there are thousands of objects being fetched, a fresh fetch takes considerable time. To mitigate this, the fetch a) uses a cache, and b) happens in the background, allowing other activities to continue
Normally, though the UI is responsive and the user can do stuff, the fetch is complete long before the user might express a desire to create a new object.
However, sometimes the app will be launched in the background - say, from a WatchKit event, or a background fetch, etc) - and part of the launch will entail creating a new object in the datastore immediately.
If the new object was created before the fetch was complete, the app would crash.
The solution is to ensure that The fetch is complete before creating an object (which would affect the fetch).
Alternatively you could delete the cache, but that is less performant practically speaking.
Note that the admonition from the debugger that
You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:
simply does not capture this situation whatsoever, in that what you have changed was not the request, predicate, or sort descriptor, but rather more accurately could be described as having mutated the result set while the fetch was in progress.
It took me forever to track down this tiny piece of trivia. I hope you benefit.
NSFetchedResultsController *fetched = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"day" cacheName:#"Events"];
replace #"Events" with nil.