Last FM API SIG_ABRT error - objective-c

I'm getting a SIG_ABRT error in the one line within the else of this method in the FMCallback class of the Last FM API.
- (void)fire {
if(_identifier == nil) {
[_target performSelector:_selector withObject:_userInfo];
} else {
[_target performSelector:_selector withObject:_identifier withObject:_userInfo];
}
}
The console output shows this:
2011-05-29 13:52:24.533 QueryTesting[6918:707] +[LastFM loginCallback:data:]: unrecognized selector sent to class 0x19550
2011-05-29 13:52:24.625 QueryTesting[6918:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[LastFM loginCallback:data:]: unrecognized selector sent to class 0x19550'
What does this mean? Am I not sending enough information with my request?
EDIT:
Here is the code to create the FMEngine (api key x'd out):
+ (void)logUserInWithUsername:(NSString *) username andPassword:(NSString *) password {
FMEngine *fmEngine;
fmEngine = [[FMEngine alloc] init];
NSString *authToken = [fmEngine generateAuthTokenFromUsername:username password:password];
NSDictionary *urlDict = [NSDictionary dictionaryWithObjectsAndKeys:username, #"username", authToken, authToken, _LASTFM_API_KEY_, #"XXXXXXXXXXXXXXXX", nil, nil];
[fmEngine performMethod:#"auth.getMobileSession" withTarget:self withParameters:urlDict andAction:#selector(loginCallback:data:) useSignature:YES httpMethod:POST_TYPE];
}
- (void)loginCallback:(NSString *)identifier data:(id)data {
// data is either NSData or NSError
NSLog(#"Got Data (%#): %#", identifier, data);
}

You've defined a -[LastFM loginCallback:data:] method, not +[LastFM loginCallback:data:].

Related

Show error messages in UIAlertView by UIAlerView+AFNetworking

There is a categroy UIAlertView+AFNetworking.h ship with AFNetworking 2.0. And I use it to show error messages in my App like this:
[UIAlertView showAlertViewForTaskWithErrorOnCompletion:task delegate:nil]
But I want to add some other messages in the message of UIAlertView.
i.e.:
StatusCode: 422
JSON Data: {"errors":{"detail":"Wrong password"}}
How to get "Wrong password" and show in a UIAlertView by the functions in UIAlertView+AFNetworking?
UIAlertView+AFNetworking category uses error messages from NSError – localizedDescription, localizedRecoverySuggestion and localizedFailureReason. AFNetworking generates NSError on failure, however, you must write your own responseSerializer to set your custom error messages there.
This topic has been thoroughly discussed on GitHub and I use solution based #camdez's code snippet.
My error response messages from API looks like this:
{ error: { message: "This username already exists" } }
Now, I've subclassed AFJSONResponseSerializer and when an error occurs, I save the error message to the NSError instance.
CustomResponseSerializer.h
#interface CustomResponseSerializer : AFJSONResponseSerializer
#end
CustomResponseSerializer.m
#implementation CustomResponseSerializer
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
id JSONObject = [super responseObjectForResponse:response data:data error:error]; // may mutate `error`
if (*error && [JSONObject objectForKey:#"error"]) {
NSMutableDictionary *mutableUserInfo = [(*error).userInfo mutableCopy];
mutableUserInfo[NSLocalizedFailureReasonErrorKey] = [[JSONObject objectForKey:#"error"] objectForKey:#"message"];
NSError *newError = [NSError errorWithDomain:(*error).domain code:(*error).code userInfo:[mutableUserInfo copy]];
(*error) = newError;
}
return JSONObject;
}
#end
Finally, you need to set appropriate responseSerializer on AFHTTPSessionManager (or AFHTTPRequestOperationManager if you use NSURLConnection API) instance. If you subclass this class as I do, you can simply do it in your init method by following:
self.responseSerializer = [CustomResponseSerializer serializer];

Problems passing data between different classes with a method

I have this in a class:
NSString *globalMidiData = #"30a0a00\n";
switch (IndicatorCheckNXT) {
case 1:
[testRobot checkTestRobot:globalMidiData];
break;
default:
break;
}
And in another class I have this:
-(void) checkTestRobot: (NSString *)midiDataGlobal{
bool pressed;
bool pressed2;
NSString *miawmiaw =[NSString alloc];
miawmiaw=midiDataGlobal;
}
And I got this message:
-[AppDelegate checkTestRobot:]: unrecognized selector sent to instance 0x18acb0
2012-11-23 20:45:31.755 Exemple1[477:707] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate checkTestRobot:]: unrecognized selector sent to instance 0x18acb0'
What I am doing wrong?
Obviously you send checkTestRobot to the wrong object. testRobot seems to point to the AppDelegate and not to an instance of your class.
Also you should replace this:
NSString *miawmiaw =[NSString alloc];
miawmiaw=midiDataGlobal;
with:
NSString *miawmiaw = [midiDataGlobal copy];

FBRequestConnection class method not found

I am trying to run a Facebook multi-query as instructed by the tutorial on the Facebook developer's site for FacebookSDK for iOS, below is the code I have in my iOS app:
-(BOOL) FBGetFriendList
{
if (FBSession.activeSession.isOpen)
{
// Multi-query to fetch the active user's friends
// Initial query is stored in reference named "friends"
// Second query picks up the "uid2" info from the first query
// and gets the friend details.
NSString *query =
#"{"
#"'friends':'SELECT uid2 FROM friend WHERE uid1 = me()',"
#"'friendinfo':'SELECT uid, name, pic_square FROM user WHERE is_app_user = 1 AND uid IN (SELECT uid2 FROM #friends)',"
#"}";
// Setup the query parameter
NSDictionary *queryParam = [NSDictionary dictionaryWithObjectsAndKeys:query, #"q", nil];
// Make the API request that uses FQL
[FBRequestConnection startWithGraphPath:#"/fql"
parameters:queryParam
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *_connection, id _result, NSError *_error) {
// check for errors here
if (_error)
{
NSLog(#"FacebookSDKPlugin > FBGetFriendList() > request error!");
}
else
{
#synchronized(friendList)
{
if (friendList == nil)
{
friendList = [[NSMutableArray alloc] init];
}
else
{
[friendList removeAllObjects];
}
NSArray *facebookData = [(NSDictionary *)_result objectForKey:#"data"];
int count = facebookData.count;
for (int i = 0; i < count; ++i)
{
NSDictionary<FBGraphUser> *tempObject = [facebookData objectAtIndex:i];
FacebookFriend *tempFriend = [[FacebookFriend alloc] initWithID:[tempObject.id copy] name:[tempObject.name copy]];
[friendList addObject:tempFriend];
}
}
}
}];
return YES;
}
return NO;
}
However, during compilation there is a warning:
Class method '+startWithGraphPath:parameters:HTTPMethod:completionHandler:' not found (return type defaults to 'id')
I ignored the error and compiled on my iPad2, which crashed with this error:
2012-09-03 11:53:13.377 +[FBRequestConnection startWithGraphPath:parameters:HTTPMethod:completionHandler:]: unrecognized selector sent to class 0xa05350
2012-09-03 11:53:13.379 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[FBRequestConnection startWithGraphPath:parameters:HTTPMethod:completionHandler:]: unrecognized selector sent to class 0xa05350'
I have included "FBRequest.h", and "Facebook.h", and I can see the method in "FBRequest.h". However I don't understand why the compiler cannot find the function. Does anybody have any idea how to solve this issue?
Opps I realized I have been using the older version of FacebookSDK, which explains why the code doesn't work as stated in the official tutorial. Updating to the latest version of the SDK (Version 3.0.8) fixed this issue!

How to deal with an empty object {} in RestKit

The response I sometimes get from the server is a JSON representing an empty object like this {}
I've read this question/answer over here already, which states I should implement the willMapData delegate function and point the *mappableData somewhere else. The thing is I can't figure out what should I assign to *mappableData so that my app won't crash.
I've tried this
- (void)objectLoader:(RKObjectLoader *)loader willMapData:(inout id *)mappableData
{
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:RKMIMETypeJSON];
*mappableData = [parser objectFromString:#"{\"unknownObject\":\"\"}" error:nil];
}
But nevertheless my app crashes with a rather pissing
'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]
Can you help me out?
UPDATE
Turning on RKDebug messages gives me this in the console:
Performing object mapping sourceObject: {
}
and targetObject: (null)
then the code reaches RKObjectMapper.m:
if (mappableData) {
id mappingResult = [self performMappingForObject:mappableData atKeyPath:#"" usingMapping:mappingsForContext];
foundMappable = YES;
results = [NSDictionary dictionaryWithObject:mappingResult forKey:#""];
}
but mappingResult over there comes back nil... so the app crashes when it tries to create an NSDictionary with a nil object.
Break up the assignment into two lines.
SomeDataType *object = [parser objectFromString:#"{\"unknownObject\":\"\"}" error:nil];
if(object){
*mappableData = object;
}else{
// You've got nil, do something with it
}
Now you can check for nil values and take the appropriate action. What that action is depends on the context of the crash.

Posting comment to YouTube with GData ObjC client library fails

I'm trying to implement commenting on YouTube videos with the gdata-objectivec-client library, using the code snippet posted in this thread; copy follows:
- (void)addCommentTitle:(NSString *)commentTitle
text:(NSString *)commentContent
toVideo:(GDataEntryYouTubeVideo *)entry {
GDataComment *commentObj = [entry comment];
GDataFeedLink *feedLink = [commentObj feedLink];
NSURL *feedURL = [feedLink URL];
if (feedURL) {
// fetch the comment feed for the video
GDataServiceGoogleYouTube *service = [self youTubeService];
[service fetchFeedWithURL:feedURL
completionHandler:^(GDataServiceTicket *ticket, GDataFeedBase *commentFeed, NSError *error) {
// callback
//
// insert a new comment into the comment feed
if (error == nil) {
GDataEntryYouTubeComment *newCommentEntry = [GDataEntryYouTubeComment commentEntry];
[newCommentEntry setTitleWithString:commentTitle];
[newCommentEntry setContentWithString:commentContent];
NSURL *postURL = [[commentFeed postLink] URL];
[service fetchEntryByInsertingEntry:newCommentEntry
forFeedURL:postURL
completionHandler:^(GDataServiceTicket *ticket, GDataEntryBase *entry, NSError *error) {
// callback
if (error == nil) {
// succeeded
}
}];
}
}];
}
}
but I always get the following exception:
*** Assertion failure in -[GDataObject setContentStringValue:](), XXXXXXXX/GData/BaseClasses/GDataObject.m:2353
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'GDataEntryYouTubeComment setting undeclared content value'
Luckily enough, I managed to make this go away by adding a new call before the comment contents are set:
GDataEntryYouTubeComment* newCommentEntry = [GDataEntryYouTubeComment commentEntry];
[newCommentEntry addContentValueDeclaration]; // <--- this method does the trick
[newCommentEntry setTitleWithString:commentTitle];
[newCommentEntry setContentStringValue:commentContent];
but it's still not OK as the request now bounces back from the server with this error:
serviceBase:<GDataServiceGoogleYouTube: 0x7a73eb0>
objectFetcher:GTMHTTPFetcher 0x7c75b20 (https://gdata.youtube.com/feeds/api/videos/XXXXXXXXXX/comments)
failedWithStatus:400
data:<errors xmlns='http://schemas.google.com/g/2005'><error><domain>GData</domain><code>ParseException</code><internalReason>[Line 2, Column 514, element entry] No converter for type class java.lang.Void</internalReason></error><error><domain>GData</domain><code>missingConverter</code><internalReason>No converter for type class java.lang.Void</internalReason></error></errors>
Has anyone else run into this issue? Is this an error on my side or Google's side?
Turns out the above code is correct, in my code I misspelled
[newCommentEntry setContentWithString:commentContent];
and used
[newCommentEntry setContentStringValue:commentContent];
instead. Now it works fine.