1

I'm doing a multithreaded CoreBluetooth app where the iPhone is working as a central, scanning (based on UI-interaction) for peripherals which then are connected and processed, resulting in various changes to the app's CoreData model used to store persistent info on the state of the different peripherals that the user has access to (without having to connected to them every time the user starts the app).

The user basically request connection to a peripheral via the UI, which then kick an async worker thread that will try to accomplish the request within a certain time-frame (e.g., a few minutes), else reporting a failure/timeout back to the UI.

Everything is working fine, but I just now started to add support for background execution since it's very likely that the users will start the async worked thread that will start to scan for BLE-peripherals, and then lock the phone and place in their pockets, expecting things to work when the peripheral is within reach.

However, Bluetooth-wise things work as they should (peripheral is discovered, connected, and processed), but I suddenly get CoreData exceptions;

CoreData: error: exception during newFetchedPKsForSourceID: I/O error for database at /var/mobile/Applications/8640B48D-8744-436A-A083-C39F63FBFB3F/Documents/Model.sqlite.  SQLite error code:266, 'not an error' errno:1 with userInfo of {
    NSFilePath = "/var/mobile/Applications/8640B48D-8744-436A-A083-C39F63FBFB3F/Documents/Model.sqlite";
    NSPOSIXErrorDomain = 1;
    NSSQLiteErrorDomain = 266;
}

CoreData: error: exception during newFetchedPKsForSourceID: authorization denied with userInfo of {
    NSFilePath = "/var/mobile/Applications/8640B48D-8744-436A-A083-C39F63FBFB3F/Documents/Model.sqlite";
    NSSQLiteErrorDomain = 23;
}

CoreData: error: exception during newFetchedPKsForSourceID: authorization denied with userInfo of {
    NSFilePath = "/var/mobile/Applications/8640B48D-8744-436A-A083-C39F63FBFB3F/Documents/Model.sqlite";
    NSSQLiteErrorDomain = 23;
}

CoreData: error: exception during newFetchedPKsForSourceID: authorization denied with userInfo of {
    NSFilePath = "/var/mobile/Applications/8640B48D-8744-436A-A083-C39F63FBFB3F/Documents/Model.sqlite";
    NSSQLiteErrorDomain = 23;
}

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'I/O error for database at /var/mobile/Applications/8640B48D-8744-436A-A083-C39F63FBFB3F/Documents/Model.sqlite.  SQLite error code:266, 'not an error' errno:1'

So, in short; all's good as long as I don't put the app in background execution mode, which to me indicate that threading and sync/merge/CoreData issues are properly setup. But something changes when the app goes into background...

Looking forward to your thoughts and ideas,

/Markus

Markus Millfjord
  • 707
  • 1
  • 6
  • 26
  • Did you enable data security for your app? If you did, you probably don't have permission to write to the CoreData store anymore... – Jason Coco Feb 26 '14 at 10:59
  • Nope, I have not enabled "data protection", if that's what you mean? But I just did a quick test removing the iPhone's pin-code protection requirement that was enabled and then things worked... But I really don'e want to force my users to remove their passwords...!? Is this where data protection comes in? – Markus Millfjord Feb 26 '14 at 11:03
  • 2
    Yeah, sorry, I couldn't remember what they called the new capability thing. Your CoreData store is definitely using it, though. When you add your store to your coordinator, add the `NSPersistentStoreFileProtectionKey` key with the value `NSFileProtectionCompleteUntilFirstUserAuthentication` to your options dictionary. That should work. – Jason Coco Feb 26 '14 at 11:08
  • I changed from the current value NSFileProtectionComplete to NSFileProtectionCompleteUntilFirstUserAuthentication, and turned the pin code protection on my phone back on -- and it works! Thank you! ;) Also, I enabled Data Protection in my project -- but my remaning question is; what did that switch "Enabled Data Protection" actually do...? – Markus Millfjord Feb 26 '14 at 11:37
  • That's really weird because `NSFileProtectionCompleteUntilFirstUserAuthentication` is supposed to be the default value for that key. – Tom Harrington Feb 26 '14 at 17:43
  • @TomHarrington, it's not really... Since I had issues setting up my main context/private context previously, and found someone who said that "I do ti like this, and it works for me" -- and THAT example had `NSFileProtectionComplete` defined as key value... Hence, my bad for copy-pasting something without realizing the consequences. – Markus Millfjord Feb 26 '14 at 20:29
  • @TomHarrington Please explain the consequences in a short answer for future reference. – allprog Mar 01 '14 at 20:51
  • 2
    @allprog the consequences of what? I was puzzled because it sounded like Markus had added code that wouldn't change anything, but he explained what was different. Makes sense to me, what are you asking about? – Tom Harrington Mar 01 '14 at 21:51
  • @TomHarrington Sorry, not consequences but conclusions. My bad. :) Having clear answers to SO questions is much better than having to parse all the comments and trying to deduct the answer. If the current one is not a real question, then delete it, close it. Anyway, I'll upvote if you post an answer because I think the underlying issue is something that many people can stumble upon. – allprog Mar 02 '14 at 15:46

0 Answers0