FatFractal customer forums



Author Topic: Update with NSDictionary  (Read 2236 times)

metakite

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Update with NSDictionary
« on: March 11, 2014, 04:30:41 PM »
I'm using the iOS FatFractal SDK, but I'm going to be using NSDictionaries instead of relying on class mapping. For example, I plan to update an object with code along the lines of:

Code: [Select]
NSDictionary *objectDictionary = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects:@"objectClazz", property1, property2, nil]
                                                                                        forKeys:[NSArray arrayWithObjects:@"clazz", kPropertyOneKey, kPropertyTwoKey, nil]];

[self.fatFractal updateObj:objectDictionary onComplete:^(NSError *err, id obj, NSHTTPURLResponse *httpResponse) {}];

(I'm planning to use NSDictionary objects instead of class mapping mostly because of the way my app is architected. I'm already producing dictionaries for my current backend, and this strategy will allow me to reuse a bunch of proven code.)

I have two questions regarding this strategy:

1. I know from http://fatfractal.com/prod/docs/datastore/#class-mapping that getObjectFromUri:onComplete: will return an NSMutableDictionary. Can updateObj:onComplete: and createObj:onComplete: accept an NSDictionary, or does it require an NSMutableDictionary as well?

2. When updating an object by feeding an NSDictionary to updateObj:onComplete:, do I have to specify all properties of the object? Or can I add only the properties that have changed (plus "clazz", of course) to the NSDictionary?

One last side question: Is the source of the iOS SDK available anywhere? (Perhaps under an open source license...) It seems like these kinds of questions could be easily answered by myself if I could peek at the code. (Code is the ultimate documentation, after all!)
« Last Edit: March 11, 2014, 04:54:38 PM by metakite »

gkc

  • Administrator
  • *****
  • Posts: 375
    • View Profile
Re: Update with NSDictionary
« Reply #1 on: March 11, 2014, 08:05:32 PM »
1) Yes you can use an NSDictionary for createObj... and updateObj... methods. They can also handle an NSMutableDictionary - reason for this is that the response from the server can include some updates which were done server-side (for example, an event handler might add a field which is generated server-side - this is a common pattern we've seen.

2) You have to specify all properties of the object.

Currently the iOS SDK is not open-sourced. However we are discussing this right now, and it's highly likely we will be open-sourcing it within the next few months.

metakite

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Re: Update with NSDictionary
« Reply #2 on: March 12, 2014, 12:28:07 PM »
I noticed that the iOS SDK doesn't require that a URI be specified when updating an object. Then I read this (from http://fatfractal.com/prod/docs/datastore/#update-an-object):

Quote
When you retrieve an object from your app’s backend, the SDK “remembers” its associated URI, allowing you to make changes to the object and store it to that same URI location.
...
Note that the update API calls require the object to have FatFractal metadata associated with it.

1. Can you give me a little more information about how the SDK remembers an object's URI?

2. Is an object's URI remembered between sessions? Or is it only remembered after it has been retrieved in the current FatFractal session?

3. Since the docs explicitly point out that the "API calls require the object to have FatFractal metadata associated with it", how will that affect my use of the SDK with NSDictionaries? Are there any special fields that I need to make sure are included in the NSDictionary so that the SDK can find the URI of the object represented by the NSDictionary?

gkc

  • Administrator
  • *****
  • Posts: 375
    • View Profile
Re: Update with NSDictionary
« Reply #3 on: March 12, 2014, 12:41:25 PM »
Hi,

Metadata is held in memory via an objc_associatedObject

If you are, for example, persisting data locally, via CoreData or anything else, the simplest possible way you can ensure that updating and deleting objects works correctly is to include "ffUrl" as a @property in your classes. The SDK will look for in-memory metadata first, and then will look for an 'ffUrl' property on the class.

I have just noticed that things don't work this way for NSDictionaries (i.e. even if your dictionary contains an ffUrl member, the SDK won't look for it). I will provide a fix for this shortly (within the hour, hopefully)

UPDATE: Actually that was incorrect. It does currently work if your dictionary contains an ffUrl member. I got confused when looking at the code. Should have looked at the tests first, since they cover this use case and they pass :-)
« Last Edit: March 12, 2014, 01:21:18 PM by gkc »

gkc

  • Administrator
  • *****
  • Posts: 375
    • View Profile
Re: Update with NSDictionary
« Reply #4 on: March 12, 2014, 01:19:17 PM »
Quote
I have just noticed that things don't work this way for NSDictionaries (i.e. even if your dictionary contains an ffUrl member, the SDK won't look for it). I will provide a fix for this shortly (within the hour, hopefully)

Update: Actually that was incorrect. It does currently work if your dictionary contains an ffUrl member. I got confused when looking at the code. Should have looked at the tests first, since they cover this use case and they pass :-)
« Last Edit: March 12, 2014, 01:21:30 PM by gkc »

gkc

  • Administrator
  • *****
  • Posts: 375
    • View Profile
Re: Update with NSDictionary
« Reply #5 on: March 12, 2014, 01:38:57 PM »
FYI here's the test harness from our unit test pack:

Code: [Select]
- (void)test_705_createObjUsingDictionary {
    [self deleteObjectsForQuery:@"/CreateObjUsingDictionary"];
    [self login];
    NSMutableDictionary *inDict = [NSMutableDictionary dictionaryWithDictionary:@{@"guid": @"IOS_obj1", @"clazz": @"CreateObjUsingDictionary", @"foo": @"12345", @"bar": @"abcde", @"baz": @NO}];
    id foo = [ff createObj:inDict atUri:@"/CreateObjUsingDictionary"];
    STAssertEqualObjects(foo, inDict, @"Failed to create using NSDictionary");

    STAssertNotNil([ff metaDataForObj:inDict], @"Metadata for created object should not be nil!");
   
    NSError *err;
    [ff updateObj:foo error:&err];
    STAssertNil(err, @"update should have succeeded (metadata in memory) : %@", [err localizedDescription]);

    NSString *ffUrl = [[ff metaDataForObj:foo] ffUrl];

    // Remove the in-memory metadata
    [ff forgetObj:foo];

    err = nil;
    [ff updateObj:foo error:&err];
    STAssertNotNil(err, @"update should have failed (no metadata in memory) : %@", [err localizedDescription]);

    // Now add ffUrl to the dictionary itself - the SDK will look for this if it can't find in-memory metadata
    err = nil;
    [foo setValue:ffUrl forKey:@"ffUrl"];
    [ff updateObj:foo error:&err];
    STAssertNil(err, @"update should have succeeded (ffUrl in dictionary) : %@", [err localizedDescription]);
   
    err = nil;
    [ff deleteObj:foo error:&err];
    STAssertNil(err, @"delete should have succeeded (ffUrl in dictionary) : %@", [err localizedDescription]);
}

metakite

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Re: Update with NSDictionary
« Reply #6 on: March 12, 2014, 03:18:51 PM »
Thanks this is really helpful. Just to be clear, what form does the ffURL take? Is it the same as the URI used by the getObjFromUri:onComplete: command? In other words, assuming I can fetch an object using this code...

Code: [Select]
FatFractal *ff = [FatFractal main];
[ff getObjFromUri:@"/MyObjectCollection/x5u5hGDUlqclCftD80IdZ7" onComplete:^(NSError *err, id obj, NSHTTPURLResponse *httpResponse) {}];

...is the ffUrl in the update below formatted correctly?
Code: [Select]
NSDictionary *dictionary = @{
    @"clazz" : myClazzValue,
    @"ffUrl" : @"/MyObjectCollection/x5u5hGDUlqclCftD80IdZ7",
    @"property1" : propertyOneValue
};

FatFractal *ff = [FatFractal main];

[ff updateObj:dictionary onComplete:^(NSError *err, id obj, NSHTTPURLResponse *httpResponse) {}];

gkc

  • Administrator
  • *****
  • Posts: 375
    • View Profile
Re: Update with NSDictionary
« Reply #7 on: March 12, 2014, 03:26:54 PM »
Right now it has to be
/ff/resources/collection/guid

I am in process of making /ff/resources prefix unnecessary (harder than it sounds, we have customers in production since 18 months ago and backwards-compatibility is of over-riding importance)

 

Copyright © FatFractal customer forums