4

How do I turn off the SQLite Write ahead logging (WAL) in Core Data using Apples new programming language Swift?

In ObjC I used to pass in the key value pair @"journal_mode": @"DELETE" in the options dictionary:

[storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                               configuration:nil
                                         URL:[self databaseURL]
                                     options:@{NSMigratePersistentStoresAutomaticallyOption: @YES,
                                           NSInferMappingModelAutomaticallyOption: @YES,
                                           @"journal_mode": @"DELETE"}
                                       error:&error]

But in Swift only the same types are allowed in a NSDictionary, so mixing BOOL (that is mapped to NSNumber) and NSString is not possible.

Any ideas?

memmons
  • 40,222
  • 21
  • 149
  • 183
kober
  • 289
  • 5
  • 12

3 Answers3

7

These answers were close but neither were actually working for me. The following does work. The option must be as as a NSSQLitePragmasOption.

var options = Dictionary<NSObject, AnyObject>()
options[NSMigratePersistentStoresAutomaticallyOption] = true
options[NSInferMappingModelAutomaticallyOption] = true
options[NSSQLitePragmasOption] = ["journal_mode" : "DELETE"]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &error) == nil {
    ...
}
Mark McCorkle
  • 9,349
  • 2
  • 32
  • 42
6

Swift dictionaries are strongly typed by default, but you can define the types your dictionary should accept.

var options = Dictionary<NSObject, AnyObject>()
options[NSMigratePersistentStoresAutomaticallyOption] = true
options[NSInferMappingModelAutomaticallyOption] = true
options["journal_mode"] = "DELETE"

[storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                               configuration:nil
                                         URL:[self databaseURL]
                                     options:opitons
                                       error:&error]

If you weren't sure what type of dictionary the function was expecting, just take a look at the function declaration :

func addPersistentStoreWithType(_ storeType: String!,
   configuration configuration: String!,
       URL storeURL: NSURL!,
    options options: [NSObject : AnyObject]!,
        error error: AutoreleasingUnsafePointer<NSError?>) -> NSPersistentStore!

It describes exactly the type of dictionary it expects -- Dictionary<NSObject, AnyObject>.

In fact, any dictionary that is bridged from Objective-C will be typed this way. From the Apple Docs:

Swift also automatically bridges between the Dictionary type and the NSDictionary class. When you bridge from an NSDictionary object to a Swift dictionary, the resulting dictionary is of type [NSObject: AnyObject].

You can bridge any NSDictionary object to a Swift dictionary because all Objective-C objects are AnyObject compatible. Recall that an object is AnyObject compatible if it is an instance of an Objective-C or Swift class, or if it can be bridged to one. All NSDictionary objects can be bridged to Swift dictionaries, so the Swift compiler replaces the NSDictionary class with [NSObject: AnyObject] when it imports Objective-C APIs.

Likewise, when you use a Swift class or protocol in Objective-C code, the importer remaps Objective-C compatible Swift dictionaries as NSDictionary objects.

Community
  • 1
  • 1
memmons
  • 40,222
  • 21
  • 149
  • 183
2

One hint, make sure you pass a Dictionary into NSSQLitePragmasOption. e.g.

url = NSBundle.mainBundle().URLForResource(name, withExtension: "momd")
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: NSManagedObjectModel(contentsOfURL: url!)!)

var err: NSError? = nil
url = dataDir.URLByAppendingPathComponent(name + ".sqlite")
options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true, NSSQLitePragmasOption: ["journal_mode": "DELETE"]]
coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &err)
mrj
  • 81
  • 1
  • 3