BJM
BJM

Reputation: 233

Write auto increment id

I'm working on a iOs program in Swift, I'm using Core Data, I tried to found how to have a auto increment id, I found this:

But no issues here, so I tried to see how to write a self auto increment attribute: I added a new attribute in my .xcdatamodeld file named "id", I found a solution in Objective-C:

https://stackoverflow.com/a/22503259/5315947

But I don't know how to parse it into Swift2

My code:

    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext

    let newDemande = NSEntityDescription.insertNewObjectForEntityForName("Demandes", inManagedObjectContext: context)
    newDemande.setValue(soapRequest.xmlString, forKey: "xml")
    newDemande.setValue(1, forKey: "statutenvoie")

    do {
        try context.save()
    } catch {
        print("erreur data")
    }

    do {
        let request = NSFetchRequest(entityName: "Demandes")
        let results = try context.executeFetchRequest(request)

        if results.count > 0 {
            for item in results as! [NSManagedObject]{
                let xml = item.valueForKey("xml")
                let statutenvoie = item.valueForKey("statutenvoie")

                print(item.objectID)
                print(xml!, statutenvoie!)
            }
        }

    } catch {
        print("erreur data")
    }

UUID error:

code:

let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext

let newDemande = NSEntityDescription.insertNewObjectForEntityForName("Demandes", inManagedObjectContext: context)
newDemande.setValue(NSUUID().UUIDString, forKey: "id")
newDemande.setValue(soapRequest.xmlString, forKey: "xml")
newDemande.setValue(1, forKey: "statutenvoie")

do {
    try context.save()
} catch {
    print("erreur data")
}

do {
    let request = NSFetchRequest(entityName: "Demandes")
    let results = try context.executeFetchRequest(request)

    if results.count > 0 {
        for item in results as! [NSManagedObject]{

            let id = item.valueForKey("id")
            let xml = item.valueForKey("xml")
            let statutenvoie = item.valueForKey("statutenvoie")

            //                    print(item.objectID)
            print(id!, xml!, statutenvoie!)
        }
    }

} catch {
    print("erreur data")
}

error:

2016-01-11 16:33:18.921 ...[2694:108875] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "id"; desired type = NSNumber; given type = __NSCFString; value = 781EFF10-A9F1-4710-98C1-6D342B2EB480.'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000110a2be65 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001132f8deb objc_exception_throw + 48
    2   CoreData                            0x00000001105c77b0 _PFManagedObject_coerceValueForKeyWithDescription + 2864
    3   CoreData                            0x000000011059f621 _sharedIMPL_setvfk_core + 177
    4   ...                             0x000000010ff690e5 _TFC7...29DemandeGratuiteViewController7ValiderfS0_FPSs9AnyObject_T_ + 4757
    5   ...                             0x000000010ff6aaa6 _TToFC7...29DemandeGratuiteViewController7ValiderfS0_FPSs9AnyObject_T_ + 54
    6   UIKit                               0x0000000112285e73 _UIGestureRecognizerSendTargetActions + 153
    7   UIKit                               0x00000001122824e5 _UIGestureRecognizerSendActions + 162
    8   UIKit                               0x00000001122804e2 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 843
    9   UIKit                               0x00000001122889a0 ___UIGestureRecognizerUpdate_block_invoke904 + 79
    10  UIKit                               0x000000011228883e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 342
    11  UIKit                               0x0000000112276101 _UIGestureRecognizerUpdate + 2634
    12  UIKit                               0x0000000111e0df8a -[UIWindow _sendGesturesForEvent:] + 1137
    13  UIKit                               0x0000000111e0f1c0 -[UIWindow sendEvent:] + 849
    14  UIKit                               0x0000000111dbdb66 -[UIApplication sendEvent:] + 263
    15  UIKit                               0x0000000111d97d97 _UIApplicationHandleEventQueue + 6844
    16  CoreFoundation                      0x0000000110957a31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    17  CoreFoundation                      0x000000011094d95c __CFRunLoopDoSources0 + 556
    18  CoreFoundation                      0x000000011094ce13 __CFRunLoopRun + 867
    19  CoreFoundation                      0x000000011094c828 CFRunLoopRunSpecific + 488
    20  GraphicsServices                    0x0000000114c2dad2 GSEventRunModal + 161
    21  UIKit                               0x0000000111d9d610 UIApplicationMain + 171
    22  ...                             0x000000010ff352cd main + 109
    23  libdyld.dylib                       0x0000000113e0a92d start + 1
    24  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

Error:

2016-01-12 09:13:03.726 ...[576:7439] CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/informatiqueresponis/Library/Developer/CoreSimulator/Devices/314EFA4E-CC21-45A0-B3FD-FA486D52BB99/data/Containers/Data/Application/B0AB216F-D9B4-408D-ADB5-92BE2D333F62/Documents/SingleViewCoreData.sqlite options:(null) ... returned error Error Domain=NSCocoaErrorDomain Code=134100 "(null)" UserInfo={metadata={
    NSPersistenceFrameworkVersion = 641;
    NSStoreModelVersionHashes =     {
        Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
        ""
    );
    NSStoreType = SQLite;
    NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
    "_NSAutoVacuumLevel" = 2;
}, reason=The model used to open the store is incompatible with the one used to create the store} with userInfo dictionary {
    metadata =     {
        NSPersistenceFrameworkVersion = 641;
        NSStoreModelVersionHashes =         {
            Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
        };
        NSStoreModelVersionHashesVersion = 3;
        NSStoreModelVersionIdentifiers =         (
            ""
        );
        NSStoreType = SQLite;
        NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
        "_NSAutoVacuumLevel" = 2;
    };
    reason = "The model used to open the store is incompatible with the one used to create the store";
}
2016-01-12 09:13:03.730 ...[576:7439] Unresolved error Error Domain=YOUR_ERROR_DOMAIN Code=9999 "Failed to initialize the application's saved data" UserInfo={NSLocalizedDescription=Failed to initialize the application's saved data, NSLocalizedFailureReason=There was an error creating or loading the application's saved data., NSUnderlyingError=0x7fded60cdae0 {Error Domain=NSCocoaErrorDomain Code=134100 "(null)" UserInfo={metadata={
    NSPersistenceFrameworkVersion = 641;
    NSStoreModelVersionHashes =     {
        Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
        ""
    );
    NSStoreType = SQLite;
    NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
    "_NSAutoVacuumLevel" = 2;
}, reason=The model used to open the store is incompatible with the one used to create the store}}}, [NSLocalizedDescription: Failed to initialize the application's saved data, NSLocalizedFailureReason: There was an error creating or loading the application's saved data., NSUnderlyingError: Error Domain=NSCocoaErrorDomain Code=134100 "(null)" UserInfo={metadata={
    NSPersistenceFrameworkVersion = 641;
    NSStoreModelVersionHashes =     {
        Demandes = <e6fa8ed7 47097048 95c90274 cbc26ea7 decd6ea3 12e0df98 cd0d3cec da84d5ff>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
        ""
    );
    NSStoreType = SQLite;
    NSStoreUUID = "7C53DEAF-C47E-446B-913E-060946C728B0";
    "_NSAutoVacuumLevel" = 2;
}, reason=The model used to open the store is incompatible with the one used to create the store}]
(lldb) 

Upvotes: 0

Views: 5798

Answers (2)

zc246
zc246

Reputation: 1514

Still confusing with the example you gave in the comment. My answer is based on my understand that you want an auto increase field - id, when next time you insert a new entry.

If you have two fields, i.e. xmlString & id. Then first you do everytime is a fetch request with SortDescriptor and setFetchLimit = 1. If the result is empty, you insert a new entry with id = 1. Otherwise, insert a new entry with id = oldId + 1.

I intentionally doesn't provide any code, because I'm not sure what you really want.

BTW, you'd better to use custom model, i.e. NSManagedObject generated by XCode, rather than the current newDemande.setValue(value, forKey: "key")

EDIT

Example code provided:

// Initialize Fetch Request
let fetchRequest = NSFetchRequest(entityName: "Demandes")

// Sort Descriptor
var idDescriptor: NSSortDescriptor = NSSortDescriptor(key: "id", ascending: false)
fetchRequest.sortDescriptors = [idDescriptor] // Note this is a array, you can put multiple sort conditions if you want

// Set limit
fetchRequest.fetchLimit = 1

var newId = 0; // Default to 0, so that you can check if do catch block went wrong later

do {
    let results = try self.managedObjectContext.executeFetchRequest(fetchRequest)

    //Compute the id
    if(results.count == 1) newId = results[0].id + 1 // slightly odd notation here, .id can be used if you use custom model. or you can use .valueForKey("id")
    else newId = 1 

} catch {
    let fetchError = error as NSError
    print(fetchError)
}

// Do the new insert afterwards

Upvotes: 3

dmlebron
dmlebron

Reputation: 861

I think you are sending a string value (781EFF10-A9F1-4710-98C1-6D342B2EB480) and core data is expecting an NSNumber (Int). Obviously, 781EFF10-A9F1-4710-98C1-6D342B2EB480 is not a number.

Core data always stores Int (Doubles, Float, etc...) values as NSNumber, for example:

let intValue
let intValueInNSNumber = NSNumber(int: intValue)

The difference is that intValue (Int) is a primitive type, while NSNumber is an object.

What's the type for the attribute "id"?

Because, if the attribute is of type "Int" you will have to change it to "String" and it should work.

Upvotes: 0

Related Questions