Monday, June 10, 2013

Xcode productivity tip: Jump to the next issue

A couple of weeks ago I began to use a feature of Xcode that improved my productivity quite a lot. For some of you this feature may be old news. To be honest: It was old news for me as well. I knew about this feature but I never used it because I could not believe that it was that useful.

Quickly jumping to the next issue

There is a keyboard shortcut in Xcode which let's you jump to the next issue (warning or error). The default shortcut for this is ⌘'. This is extremely handy - especially if you have a "zero-warning policy" because then every issue is worth fixing immediately: You won't jump to an issue which you can fix later or which is not really an issue.

I decided to assign the "Jump to Next Issue" command a simple shortcut just to make things easier for me. Because I have a German keyboard i am using ⌘Ä to jump to the next issue and ⌘Ö to jump to the previous issue.

Update:
You may have to restart Xcode for the new key bindings to take effect.

Thursday, May 23, 2013

Core Data Editor and RestKit

Lasse Moos, a user of Core Data Editor, contacted me because when he tried to use Core Data Editor all he got was this:

(The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store.)

We wrote back and forth but with no success. Luckily Lasse agreed to share his screen with me. In that session I had access to his Xcode project and was able to look at the issue first hand. At some point he mentioned that he is using RestKit in this project. When I first had a look at RestKit when it came out I knew that this framework was not made for me. But this is a totally different story. What I did not know about RestKit is that RestKit seems to modify the managed object model at runtime to do it's magic. This is a problem for Core Data Editor because the managed object model of your store file has to match the version of your model which is inside your app bundle.

I know that many people around the globe are using RestKit and I will try to offer some kind of workaround although I don't want to support RestKit in any way. :)

I am glad to finally know why a relatively large user base has problems with Core Data Editor. Thank you Lasse.

Saturday, January 5, 2013

iCloud causes major depressions

iCloud makes me feel dumb. That's it. Good night.

Sunday, June 17, 2012

Core Data Editor + Sandboxing = trouble

I just realized that the current Mac sandboxing situation makes a new major version of Core Data Editor impossible/not practical. A few weeks ago I published a blog post which describes an issue related to Core Data and sandboxing. Let me sum this post up really quickly: If you have a SQLite store it creates a temporary file during the save operation in order to be able to roll back in case something goes wrong.  The sandbox mechanism cannot handle this at the moment and therefor the save operation fails. Basically there are two workarounds (as described in the linked blog post):

  1. disable the creation of the journal file - this has bad side effects
  2. wrap the SQLite store file in a folder
Core Data Editor is a tool for developers which allows them to inspect and edit the data in a store file so the workarounds are not possible. The first workaround is not possible because it would lead to inconsistent data and Core Data Editor would be hold responsible for this. Workaround number two is a good workaround for 99% of the developers but I am in the situation that I cannot do this because Core Data Editor is a generic application. You should be able to throw anything at it - not only SQLite files wrapped inside a folder. Core Data Editor is not the only application having this problem. Basically any SQLite editor out there has this problem. One prominent example is Base from Menial - a competitor of Core Data Editor when it comes to editing Core Data SQLite stores.

The problem is more widespread

In my opinion the problem is even more widespread: Every application that can edit files through a library that has to generate temporary files in locations not supported by the sandbox mechanism is out of luck. I really hope that Apple is considering this Core Data issue something they have to fix. But how do we expect them to fix this? The journal file causing the problem is not created by Apple directly. The underlying SQLite library used by Core Data is creating the temporary file. Do we want Apple to go through every third party library and adjust the sandboxing mechanism according to the implementation details of these libraries? I guess not but in my opinion the problem described above is special. Core Data is an integral part of Cocoa and Cocoa Touch. It is an awesome framework. I fell in love with Core Data when it first came out with 10.4 (Tiger). Hell - I am even writing a whole book about Core Data. It is heavily pushed by Apple. Core Data is supposed to make iCloud a piece of cake for developers. Apple - please make an exception so that Core Data Editor can receive major updates and to make life easier for the other developers not using bundle-based file formats.

Monday, May 28, 2012

Core Data, Document-Based Application and Sandboxing

Every now and then one of my customers using Core Data Editor sends me a Core Data related question via e-mail. The last Core Data related question I got went like this:

I have a Core Data Document-Based application that is using the SQLite store. When I activate sandboxing I am not able to save the context anymore. Why is that and how can I work around this problem?
This question really caught my interest. Here is what I found out:

The save fails because the underlying SQLite library created temporary files on behalf of Core Data. You may have seen a file like this. Usually this file has the suffix "-journal". When you activate sandboxing your application is only are allowed to read and write to the store file itself and not to the "-journal" file. This explains why the save of the context fails. Until Apple has fixed this you can work around this by deactivating the creation of journal files. You can do this by sending the following pragma statement to the SQLite database:

pragma journal_mode OFF
or
pragma journal_mode MEMORY


Let me explain:
The first pragma statement completely disables the journaling of SQLite. You usually don't want to do this because you can't do a rollback anymore. The second pragma statement has less dramatic side effects: You can still rollback but the bookkeeping is done in memory. If your transactions are small this won't be a problem but you should be aware of the side effects.
Now that we know that its time to think about Core Data again. Core Data does not expose the SQLite database handle to the developer - with good reasons. Nevertheless there is a way that allows us to send the pragma statement to the SQLite database used by the SQLite store. When you add a persistent store to a coordinator you can specify an options dictionary. There is a key called NSSQLitePragmasOption that lets you specify another dictionary that contains the pragma statements you want to be executed by the SQLite store. I have described the procedure on Stackoverflow.com. Here is the code snippet that sets the journal mode to MEMORY:


NSDictionary *pragmaOptions = [NSDictionary dictionaryWithObject:@"MEMORY" 
                                                          forKey:@"journal_mode"];


NSDictionary *storeOptions = [NSDictionary dictionaryWithObject:pragmaOptions 
                                                         forKey:NSSQLitePragmasOption];


NSPersistentStore *store;
NSError *error = nil;
store = [psc addPersistentStoreWithType:NSSQLiteStoreType
                          configuration: nil
                                    URL:url
                                options:storeOptions
                                  error:&error];   

The last step is to bring it all together. In your NSPersistentDocument subclass you have to override the method that sets up the coordinator like this:

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error {
   
   NSDictionary *pragmaOptions = [NSDictionary dictionaryWithObject:@"MEMORY" 
                                                             forKey:@"journal_mode"];
   
   NSDictionary *options = [NSDictionary dictionaryWithObject:pragmaOptions 
                                                        forKey:NSSQLitePragmasOption];
   
   return [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:options error:error];
}


A more "secure" solution is to create a package and put in your store file there. This requires no pragma-voodoo. You can find a discussion about this topic in the developer forums. (Account required)

If you have found a better solution please send me an e-mail.



Flashcards Pro for iPad released

It was a long journey but I am pleased to announce that Flashcards Pro for iPad is now available in the App Store. Flashcards Pro is beautiful and easy to use application, that helps you learn new things quickly and efficiently. Here is a short video I made that should give you a good impression:



Over the next several months the iPad application will become a universal application that also runs on your iPhone and iPod Touch. The Mac application will also get a major update. The plan is to enable iCloud as soon the Mac application has been updated or the iPad app became universal. If you have feedback please send it directly to me via email.

Saturday, April 21, 2012

Flashcards for iPad: Status

Flashcards for iPad is doing well. The beta test has started approximately one week ago. Flashcards for iPad is more or less feature complete and with the help of the beta testers I am able to work out the rough edges. Once Flashcards for iPad has been released I will work on a major new version of Flashcards for Mac in order to enable iCloud syncing.