Unable to fetch related item from DynamoDB using Core Data - ios

I have two entities with a one to one relationship between the two. In tests I can create the two entities, join and save them. The data appears in DynamoDB as expected with the appropriate ID's displayed to show the two are related.
I then attempt to retrieve the items back. I perform a fetch request for one of the items, which is returned and I can log it's identifier successfully. However, if I attempt to log the identifier of the related entity which I am expecting to have been fetched implicitly I get the following exception:
2013-01-17 15:00:13.936 DJ[10995:c07] DynamoDBResponse.m|-[DynamoDBResponse connectionDidFinishLoading:]|62|Response Body:
{"__type":"com.amazon.coral.validate#ValidationException","message":"1 validation error detected: Value null at 'key.hashKeyElement' failed to satisfy constraint: Member must not be null"}
2013-01-17 15:00:13.936 DJ[10995:c07] DynamoDBResponse.m|-[DynamoDBResponse connectionDidFinishLoading:]|92|Returned CRC32: 650439770, Calculated CRC32: 650439770
2013-01-17 15:00:13.937 DJ[10995:c07] AmazonRequestDelegate.m|-[AmazonRequestDelegate request:didFailWithServiceException:]|74|didFailWithServiceException
2013-01-17 15:00:13.937 DJ[10995:c07] DynamoDBWebServiceClient.m|-[DynamoDBWebServiceClient invoke:rawRequest:unmarshallerDelegate:]|131|Response Status Code : 400
2013-01-17 15:00:13.938 DJ[10995:c07] AmazonErrorHandler.m|+[AmazonErrorHandler errorFromExceptionWithThrowsExceptionOption:]|51|WARNING: An exception was thrown. Please call [AmazonErrorHandler shouldNotThrowExceptions] to change this behavior.
2013-01-17 15:00:13.939 DJ[10995:c07] *** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x7540100 <x-coredata://279744BC-1B25-4170-AF2C-83676954BC3D-10995-00005B7C38D21AFA/Venue/p(null)>''
*** First throw call stack:
(0x1655012 0x147ae7e 0xe6ed8 0xe6887 0xe64c1 0xe6336 0x10b000 0x260c 0x1edc 0x4a3817 0x4a3882 0x3f2a25 0x3f2dbf 0x3f2f55 0x3fbf67 0x3bffcc 0x3c0fab 0x3d2315 0x3d324b 0x3c4cf8 0x24a2df9 0x24a2ad0 0x15cabf5 0x15ca962 0x15fbbb6 0x15faf44 0x15fae1b 0x3c07da 0x3c265c 0x282d 0x1d15)
libc++abi.dylib: terminate called throwing an exception
I have tried setting:
[request setReturnsObjectsAsFaults:NO];
but there is no difference in the result.
I am not performing any updates on the data following the initial fetch. Am I missing something?
<< EDIT 1 >>
I can see from the logging that when accessing the related object, the underlying message being sent to DynamoDB has a null key, so it is correct that DynamoDB can't fetch a result, but I don't understand why the key isnot being transmitted, as it is correctly listed in the DB.
<< EDIT 2 >>
If I add a second relationship which is one to many and add the exact same entity into it, then access the one to many relationship first, I can then retrieve the exact same object via the one to one relationship as expected . . . has anyone got an example where they have successfully used DynamoDB for a one to one relationship as this seems like a bug?

It seems DynamoDB cannot handle null or empty string values (instead, you shouldn't have an attribute at all), and that may be hitting you.
Can you do a similar query outside your app ? in the 'console' ?

I'm afraid this never got solved, but there is a more detailed thread on the AWS forums if anyone is interested - https://forums.aws.amazon.com/thread.jspa?threadID=114528&tstart=0
End result was that I could not get a one to one relationship to fire, without including the same related entity in a one to many relationship and accessing that first, even though the exact same relationship worked exactly as expected when backing onto SqlLite.

Related

Illegal attempt to establish a relationship 'order' between objects in different contexts

The orderDetail is related with consume. The consume was fetched from CoreDataContext as a parameter passed to here and was exist.
orderDetail = [NSEntityDescription insertNewObjectForEntityForName:#"OrderDetail" inManagedObjectContext:CoreDataContext];
orderDetail.order = consume
But this code throws an exception:
Illegal attempt to establish a relationship 'order' between objects in different contexts
I checking the exception with NSLog
NSLog(#"%#", orderDetail.managedObjectContext);
NSLog(#"%#", consume.managedObjectContext);
Then I found that orderDetail.managedObjectContext exists, but the consume.managedObjectContext is nil
Is this why the exception threw? I don't know why this happened.
Update my question,more info:
First
I have only one Context
Second
this is happened when I delete the consume-entity and reinsert consume-entity:
When I push A viewController to B viewController(B viewWillAppear) I request the orderDetail and established the relation of consume,when I pop to A in method viewWillAppear I request consume ,when I received data I called
[ CoreDataContext performBlock:^{
[Consume cleanTheContext:CoreDataContext];...
... ... ... ...
for (NSDictionary *consume in consumes) {
[Consume consumeWithLecaiInfo:consume inManagedObjectContext:CoreDataContext byUser:user];
}];
to clean the old consume and insert new consume (I know I should update consume ,rather than delete and reinsert,but I don't know why consume lost it's managedObjectContext in this way)
In reality this error occur once in a while , push A,pop B, push A, pop B ... exception threw out .
Error is self explanatory, you can modify you code to retrieve consume object from the same context where you create orderDetail:
OrderDetail *orderDetail = [NSEntityDescription insertNewObjectForEntityForName:#"OrderDetail" inManagedObjectContext:CoreDataContext];
orderDetail.order = [CoreDataContext objectWithID:consume.objectID];
objectID is a proper way to transfer objects from one NSManagedObjectContext to another
For a relationship to be formed both objects must be created from the same NSManagedObjectContext.
Normally this is not an issue because your UI should be using a single context and your creation of objects should be using NSEntityDescription.insert....
Since you have a nil context in one of your objects, that means you are creating it either with a nil context somewhere or you are intentionally passing a nil into NSManagedObjectContext.init.... Either situation is a problem.
Trace your creation code and put breakpoints in. Find where the nil is and fix it.

Core Data predicate to filter by a subentity attribute

I have been looking for this but I found nothing and I think it's unsupported by Core Data. Anyway, let's see it:
I have 3 entities: Ticket, TicketLine and CheffLine.
Now I want to fetch the tickets (by means of a NSFetchedResultsController), but filtering the tickets that have at least one CheffLine with a cheffStatus greater than 0. The problem is that cheffStatus is an attribute of the CheffLine entity, so I make this predicate:
[NSPredicate predicateWithFormat:#"0 != SUBQUERY(lines, $x, $x.cheffStatus > 0).#count)"];
But when executed, I get this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to generate SQL for predicate (0 != SUBQUERY(lines, $x, $x.cheffStatus > 0).#count) (problem on RHS)'
I noticed that if the query is done using $x.someVariableInTheTicketLineEntity instead of $x.cheffStatus, it works. I also tried to use CAST, but obtained the same result
[NSPredicate predicateWithFormat:#"0 != SUBQUERY(lines, $x, CAST($x, 'CheffLine').cheffStatus > 0).#count)"];
Is there any way of doing this query? Remember that it must work inside a NSFetchedResultsController.
Ok, I found that there's no solution. Look at this:
How can you reference child entity name in a predicate for a fetch request of the parent entity?
The way to go is to fetch the results in 2 separate requests and then merge manually, so forget about the NSFetchedResultsController.

Saving NSManagedObjectContext on Stackmob -- uploads to server, but crashes app

I have been running into an issue in using StackMob as the backend of my iOS application (though I'm not sure if this is an issue in wrongly using StackMob's methods or an iOS issue).
I am allowing a user to create a post object that is just a subclassed NSManagedObject, and uploading that to the server to be used in other parts of the application. The issue that arises occurs in the method:
[NSManagedObjectContext saveOnSuccess:<^(void)successBlock> onFailure:<^(NSError *error)failureBlock>];
Here, I am using a StackMob method for asynchronously saving the MOC found in the NSManagedObjectContext(Concurrency) Category Reference.
The view before this one performs a fetch on recent posts, and in the case where the fetch is not performed posting works fine, but if a fetch was performed then in saving the MOC in order to upload the new post I receive the following output as an error message:
2013-09-11 17:08:09.284 imageTagging[1824:1843] -[__NSDictionaryI bytes]: unrecognized
selector sent to instance 0x1e3123d0
2013-09-11 17:08:09.291 imageTagging[1824:1843] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI bytes]: unrecognized
selector sent to instance 0x1e3123d0'
*** First throw call stack:
(0x318cb3e7 0x395c6963 0x318cef31 0x318cd64d 0x31825208 0x321631cf 0x3216b991 0x15ea99
0x318c8757 0x15e109 0x15dabf 0x10d1c3 0x318d05b7 0x10cd4d 0x10c829 0x10923b 0x1076d9
0x3166c431 0x316c44d1 0x1685c3 0x316c7e5d 0x399e3b3b 0x399e167d 0x399e4613 0x399e47d9
0x39a087f1 0x39a08684)
libc++abi.dylib: terminate called throwing an exception
(lldb)
The data is still uploading to the StackMob server, and can be called upon when the app is run later -- but the app crashes in trying to save it. All of this is performed in the view controller. I've tried to enforce all MOC saves to be performed on the main thread, but the error still occurs. I've also tried dispatching a "save queue" and updating the UI after save completes. This method seemed to work for a bit, but then the errors came up again (may have just been a fluke). I also tried to do this with the synchronous save calls in the documentation
The same error occurs when trying to perform other saves as well (such as after creating a new user or when updating a user's information), and all come down to the same function call causing the problems. It may also be worthwhile to note that the error is always the same (specifically that a type __NSDictionaryI is trying to access its unrecognized selector bytes.
Here is the full method call with the input parameters filled out:
//save context
[[[[SMClient defaultClient] coreDataStore] contextForCurrentThread] saveOnSuccess:^{
NSLog(#"You created a new Post object!");
[[[[SMClient defaultClient] coreDataStore] contextForCurrentThread] refreshObject:newPost mergeChanges:YES];
NSLog(#"refreshed");
} onFailure:^(NSError *error) {
NSLog(#"There was an error! %#", error);
}];
UPDATE: I have narrowed down the problem to a mishandling of information returned from a fetch performed by the previous view controller. Specifically, it occurs after the results are fetched in trying to use the data to update.
As a result of this new insight, the question I am really facing is how to properly save a managed object in the context after a fetch. I believe StackMob takes care of creating the managed objects after the fetch (i.e. server query). I've tried creating a new object from the results array (each "obj" is an NSManagedObject) with:
[results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSManagedObject *newObj = obj;
}];
I've also tried referencing the fetched results by object id (each "obj" is an objectID) with:
[results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSManagedObject *newObj = [self.managedObjectContext objectWithID:obj];
}];
Any insight on how to properly do this would be greatly appreciated!
UPDATE 2: It looks like the error is actually occurring in trying to use and save geolocation data. In order to use the queried objects' geolocation data, it must be unarchived -- but to save it, it must be archived. I'm looking into how to do this now, and if I come across a good solution, I'll update again.
FINAL UPDATE: Got it figured out! It turns out that the issue I was having was that I was unarchiving the geolocation data to update the UI and do some calculations, and while I was archiving it again to be stored properly, I created an annotation on a map that referenced the unarchived data. As a result, the MOC maintained the data that could not be saved via the StackMob methods. By only saving the archived data, I can save as often as I'd like and just unarchive the geodata when it needs to be used. Problem solved!
Please feel free to comment if anyone comes across a similar problem and needs some insight or references!
I am just going to put my final update in here as an answer, since it explains how I solved the issue.
FINAL UPDATE: Got it figured out! It turns out that the issue I was having was that I was unarchiving the geolocation data to update the UI and do some calculations, and while I was archiving it again to be stored properly, I created an annotation on a map that referenced the unarchived data. As a result, the MOC maintained the data that could not be saved via the StackMob methods. By only saving the archived data, I can save as often as I'd like and just unarchive the geodata when it needs to be used. Problem solved!
Please feel free to comment if anyone comes across a similar problem and needs some insight or references!
Moral of the story, if you are running into issues similar to this, make sure you are not (even if you don't mean to be) storing references to the unarchived SMGeoPoint data in any of your managed objects. It is trying to store those that causes the problem.

Assertion failure in -[NSIndexPath row] with AppList dataSource

See update below.
I'm writing a tweak and am using AppList. I am hooking into spotlight and creating a table off all installed applications. I am trying to use the dataSource to get the information (display identifier etc). The problem is if dataSource is defined... I get the following error:
SpringBoard[1622] <Warning>: *** Assertion failure in -[NSIndexPath row], /SourceCache/UIKit/UIKit-2380.17/UITableViewSupport.m:2680
SpringBoard[1622] <Warning>: ***** AltKeyboard Uncaught Exception: Invalid index path for use with UITableView. Index paths passed to table view must contain exactly two indices specifying the section and row. Please use the category on NSIndexPath in UITableView.h if possible. *****
or
SpringBoard[1890] <Warning>: ***** AltKeyboard Uncaught Exception: *** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1] *****
SpringBoard[1890] <Error>: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
*** First throw call stack:
If dataSource is not defined and I use fake data (test name), the table is generated fine. When I print the dataSource there are only two items in it.
Ryan Petrich, on IRC, seemed to suggest that I was doing everything completely wrong but wasn't much help after that. Perhaps I am going about solving this problem incorrectly?
Code: http://pastebin.ca/2457626
Repository: https://github.com/twodayslate/ListLauncher
edit/update!
dataSource is giving me problems. It isn't fetching the same number of apps and thus I am getting index errors and the like. I have over 200 apps but dataSource is only fetching 2.
The following code gives no errors but only displays 2 items: http://pastebin.ca/2458961
edit!
I changed it so I just use ALApplicationList. I am able to get all the applications listed. However, when I attempt to scroll through the table, it crashes. Sorting and creating the list is really slow so I believe that might be causing the problem. I'm no pro at obj-c so I'm sure there is a better way than what I am doing. http://pastebin.ca/2459318
Your problem is twofold. First, UITableView expects to be handed index paths containing both a row and a section, where you've provided it with only a row. Second, you cannot expect unchecked array access to succeed 100% of the time, so bounds check whatever access calls you might be using. It also wouldn't hurt to use some retains in the iVar assignments you've got in your code unless you don't need to hold a reference to it (but it looks like you do).
I figured out an alternative solution to ALDataSource. I sorted ALApplicationList.applications. The problem was that the instance of the sorted NSArray would keep disappearing. So I did [values retain] and everything worked! Reinitializing the sorted values was too slow and would crash the device.
Here is the working code that successfully lists all the apps: http://pastebin.ca/2459778

Why am I getting a `unrecognized selector sent to instance` error?

I have a Ruby on Rails application that has an API, it's an OAuth 2.0 provider and uses Doorkeeper. I am creating an iPhone client for that application and am using the gtm-oauth2 library for authentication. Here is the Github repository for the iPhone app.
I manage do the authentication request using the library and get the response from the OAuth server, but (I think that) when the iPhone app receives the response, the iPhone app crashes. I get the following error:
2013-03-25 07:30:51.563 Catapult for iOS[68917:c07] -[NSNull length]: unrecognized selector sent to instance 0x14f2678
2013-03-25 07:30:51.564 Catapult for iOS[68917:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x14f2678'
*** First throw call stack:
(0x13c1012 0x11e6e7e 0x144c4bd 0x13b0bbc 0x13b094e 0xf074 0x185e3 0x13b51bd 0x13b50d6 0x1531a 0x1512b 0x14ae2 0x13b51bd 0x13b50d6 0x11d0a 0x1032a 0x13b51bd 0x13b50d6 0x79be 0x77ed 0x8cf2 0xcec589 0xcea652 0xceb89a 0xcea60d 0xcea785 0xc37a68 0x4a2a911 0x4a29bb3 0x4a67cda 0x13638fd 0x4a6835c 0x4a682d5 0x4952250 0x1344f3f 0x1344a39 0x1367734 0x1366f44 0x1366e1b 0x22be7e3 0x22be668 0x12affc 0x2c6d 0x2b95)
libc++abi.dylib: terminate called throwing an exception
I am a complete noob/beginner when it comes to iOS development and Objective-C programming, and I am learning how to create my first app using this little project. I asked the same question in the gtm-oaut2 Google Group and according to them, the problem comes from my code and not the library. The problem is that all of my code is taken from their wiki and I can't pinpoint where the app crashes. If I understand correctly, at some point I am calling length of NSNull, but I am not calling length anywhere, hence my confusion. Also, when the app crashes, the line hilighted is in the main.m file and the error (on the right label, not in the output) is the following:
Thread 1: signal SIGABRT
I have no clue what that means...
Does anyone know what the problem might be please?
You're right that the issue is that somewhere you've got the length message being sent to an instance of NSNull. To pinpoint where exactly this is happening set a breakpoint on objc_exception_throw. You can do this in the Xcode UI with little "+" button in the bottom left corner on the breakpoints tab. Select "Add Exception breakpoint." Then the debugger will stop your program at the point where the error occurs instead of waiting for the program to actually crash.
Well... you understood the error correctly.. You are somewhere calling length on a NSNull instance.
I must find out where this is happening.
I think this is happening in a JSON response. Maybe you (or "the code") is calling length on something it expects its a NSString but it is instead NSNull (that is the json has a NULL value).
Try if you manage to print the json response and see if you found a key mapped to a null value...
NSNull does not respond to length
You can check the documentation for NSNull to see that this is the case.
Without having an idea of what your code base is doing I am not sure where to look, you must be calling [NSNull null]; at some point to get the NSNull object or you are using a framework somewhere that returns this.

Resources