Getting isEqualToString: unrecognized selector sent to instance error - iphone

I'm getting this error when clicking the same UIButton twice, it crashes the second time only when the request to the server is not able to go through.
-[SendHelloFax isEqualToString:]: unrecognized selector sent to instance 0x12b49150
Update: I used breakpoints and found that the line it is crashing at is:
if (!errorMessage || [errorMessage isEqualToString:#""])
{
errorMessage = #"Failed to send fax. Please check your WiFi or 3G connection and try again.";
}
Methods:
- (IBAction)sendFaxButtonClicked:(id)sender
{
NSString *errorMessage;
int rcode = [MyDataSource sendFax:self.appointment phone_call_id:self.phone_call_id document_url:self.document_url targetId:self.contact_id targetName:self.name.text targetNumber:self.faxNumber.text coverSheetMessage:self.coverSheetMessage.text errorMessage:&errorMessage];
if (rcode) {
if (!errorMessage || [errorMessage isEqualToString:#""]) {
errorMessage = #"Failed to send fax. Please check your WiFi or 3G connection and try again.";
}
UIAlertView *someError = [[UIAlertView alloc] initWithTitle: #"Error" message:errorMessage delegate: self cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[someError show];
[someError release];
return;
}
if (!rcode) {
[self dismissModalViewControllerAnimated:FALSE];
}
}
+(int)sendFax:(int)appointment_id phone_call_id:(int)phone_call_id document_url:(NSString*)document_url targetId:(int)contactId targetName:(NSString*)targetName targetNumber:(NSString*)targetNumber coverSheetMessage:(NSString*)coverSheetMessage errorMessage:(NSString**)errorMessage
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/ichrono/20110715/60b88126/fax_send/", [self getMyHost]]];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[self addCurrentUserLoginToPostRequest:request];
[request setPostValue:[NSString stringWithFormat:#"%d", contactId] forKey:#"fax_contact_id"];
[request setPostValue:[NSString stringWithFormat:#"%d", appointment_id] forKey:#"appointment_id"];
[request setPostValue:[NSString stringWithFormat:#"%d", phone_call_id] forKey:#"phone_call_id"];
[request setPostValue:document_url forKey:#"url_to_fax"];
[request setPostValue:targetNumber forKey:#"fax_number"];
[request setPostValue:targetName forKey:#"full_name"];
[request setPostValue:coverSheetMessage forKey:#"coversheet_message"];
[request startSynchronous];
NSError *error = [request error];
NSString *responseString;
if (!error) {
responseString = [request responseString];
} else {
return -1;
}
NSMutableDictionary *temp = [responseString JSONValue];
*errorMessage = [temp valueForKey:#"errors"];
if ([[temp valueForKey:#"status"] isEqualToString:#"ok"]) {
return 0;
} else {
return -1;
}
}

Best bet is that errorMessage is not initialized and not set to a NSString even though rcode is not 0.
Try: NSString *errorMessage - nil; and checking to insure errorMessage is set in this instance.

When, at the beginning of your method, you define - without initialization -:
NSString *errorMessage;
you're in fact defining an id which has not been set to a valid value (that is a valid string using alloc-init or simply nil) so the memory area content pointed by errorMessage is not valid, that is it can be anything: an invalid area (which will lead to EXC_BAD_ACCESS) or another area previously taken by a now dealloc'd class (like in your case: this will raise an invalid selector exception) or in the worst case an area taken by another now dealloc'd NSString (difficult to debug!).
Later you call sendFax:phone_call_id:... method which returns rcode and has as side effect to update the errorMessage pointer by let it point to a valid address (or nil). It doesn't and then when you check errorMessage you get one of the errors above.
I suppose from your code that when rcode is set some error occurred. In such case this method must assign something to errorMessage, even a nil or an empty string, to avoid this error. So probably the sendFax: method is missing this detail.

Related

How to solve json Error in ios 7?

Am using following code.
+(void)getQuarterList:(NSString *)user_id
{
if ([self checkInternet])
{
NSString *url=[NSString stringWithFormat:#"%#/api/v1/quarters.json",MainURL];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"id":user_id};
// NSDictionary *parameters = #{};
// NSDictionary *parameters = #{#"id":user_id,#"auth_token":auth_token};
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *dict=[[NSDictionary alloc]initWithDictionary:responseObject];
//NSMutableArray *dict=[[NSMutableArray alloc]initWithArray:responseObject];
NSLog(#"dict%#",dict);
if ([dict valueForKey:#"Success"])
{
NSNotification *notif1 = [NSNotification notificationWithName:#"quarterDetailsNotifier" object:[dict valueForKey:#"Success"]];
[[NSNotificationCenter defaultCenter] postNotification:notif1];
}
else if ([dict valueForKey:#"noData"])
{
NSNotification *notif1 = [NSNotification notificationWithName:#"noDateNotifier" object:[dict valueForKey:#"Error"]];
[[NSNotificationCenter defaultCenter] postNotification:notif1];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
NSNotification *notif1 = [NSNotification notificationWithName:#"quarterDetailsFailNotifier" object:error];
[[NSNotificationCenter defaultCenter] postNotification:notif1];
}];
}
else
{
NSNotification *notif1 = [NSNotification notificationWithName:#"internetFailNotifier" object:nil];
[[NSNotificationCenter defaultCenter] postNotification:notif1];
}
}
am having following error
2014-05-20 15:39:33.610 TMLP[2770:a0b] The internet is working via WIFI.
2014-05-20 15:39:35.733 TMLP[2770:a0b] Error: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x8e4a1a0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set., NSUnderlyingError=0x8e65ca0 "Request failed: not found (404)"}
2014-05-20 15:39:35.734 TMLP[2770:a0b] -[NSError length]: unrecognized selector sent to instance 0x8e4a180
2014-05-20 15:39:35.737 TMLP[2770:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSError length]: unrecognized selector sent to instance 0x8e4a180'
* First throw call stack:
how to solve this error
You post error as an object of NSNotification. And in notifcation handler you use it as NSString or other object that has method length.
First things first.
Your obtained JSON text should always start with a "[" or "{" for the parser to recognise it. And the reason you are getting this error is clearly because this is not fulfilled.
I suggest you check your JSON text through a JSON validator which is available online.
And the Second thing I Suggest is to use for JSON Serialization/Deserialization is
NSJSONSerialization
And Example would be like this :
NSDictionary *jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error: &error];
The options:NSJSONReadingAllowFragments might solve your problem of parsing fragments that you are getting right now. If this doesn't help, another option would be to extract out the proper JSON string from the obtained fragmented string.This means eliminating the extra unwanted characters from the starting and end of the string.
An Example would be like this :
NSURL *url=[NSURL URLWithString:#"yourURL"];
NSData *response = [NSData dataWithContentsOfURL:url];
NSString *badjsonData = [NSString stringWithUTF8String:[response bytes]];
NSString *goodJsonData = [badjsonData substringFromIndex:76];
NSString *finaljsonData = [goodjsonData substringToIndex:[goodjsonData length]-9];
NSData *goodData = [finaljsonData dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *jsonArray = [NSJSONSerialization JSONObjectWithData:goodData options:NSJSONReadingAllowFragments error: &error];

Error 204, The Request Did not Return any Content While Posting data to Twitter

I tried to post from twitter but it not posting the comments. It display an error 204 , in the facebook the same data is successfully posted but in the twitter i got an error can any one have an idea How to solve it
-(void)postDataOnTwitterMethod{
if ([[FHSTwitterEngine sharedEngine]isAuthorized]) {
NSData *dataFromPath = UIImageJPEGRepresentation(cameraImage,1.0);
number = (arc4random()%10000)+1; //Generates Number from 1 to 10000.
RndNo = [NSString stringWithFormat:#"%i", number];
NSLog(#" ITEM %#",RndNo);
NSString *avalabelDate = [NSString stringWithFormat:#"%#_%#",[CommonMethods getCurrentDateAndTime],self.AvailableTillTextField.text];
NSString *theWholeString = [NSString stringWithFormat:#"Item No: %#\nItemName: %#\nItemCost: %#\nAvailableTill: %#\nCategory: %#\nDescription: %#",RndNo,self.NameTextField.text,self.PriceTextField.text,avalabelDate,self.ListTypeTextField.text,self.DecTextView.text];
dispatch_async(GCDBackgroundThread, ^{
#autoreleasepool {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSError *returnCode = [[FHSTwitterEngine sharedEngine]postTweet:theWholeString withImageData:dataFromPath];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *title = nil;
NSString *message = nil;
if (returnCode) {
title = [NSString stringWithFormat:#"Error %d",returnCode.code];
message = returnCode.localizedDescription;
} else {
title = #"Tweet Posted";
}
dispatch_sync(GCDMainThread, ^{
#autoreleasepool {
UIAlertView *av = [[UIAlertView alloc]initWithTitle:title message:message delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
}
});
}
});
}
else{
[[FHSTwitterEngine sharedEngine]showOAuthLoginControllerFromViewController:self withCompletion:^(BOOL success) {
NSLog(success?#"L0L success":#"O noes!!! Loggen faylur!!!");
}];
}
}
Your comments made me smile.
I believe it's an HTML error. It means the data was received and understood but you shouldn't expect a return. In other words, it's void. At least that's what I can see with a quick look around your code and my minimal understanding of Twitter API.
Now i am able to send the String but cant able to send the Image using this method
NSError *returnCode = [[FHSTwitterEngine sharedEngine]postTweet:theWholeString withImageData:imageData];
FHSTwitterEngine has some known bugs, and the problem is now fixed, see below:
Getting error while posting image using FHSTwitterEngine
compress the existing image with this code and you will get images posted.
NSData *data = UIImageJPEGRepresentation(imageView.image, 0.6);

Logic Issue - NSObject class - Beginner

I have 2 questions.
1.) I am creating a NSObject class, and i am having the following code in it. (ASIHTTPRequest POST).
The name of the NSObject class is called, SendToServer. I call the class as follows;
SendToServer *sv = [[SendToServer alloc]];
sv.grabURLInTheBackground ;
NSLog(#"This line is executed ");
The following is the code that is in the SendToServer NSObject class.
- (void)grabURLInTheBackground
{
if (![self queue]) {
[self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
}
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestWentWrong:)];
[[self queue] addOperation:request]; //queue is an NSOperationQueue
}
- (void)requestDone:(ASIHTTPRequest *)request
{
NSString *response = [request responseString];
}
- (void)requestWentWrong:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
The problem is that, the code executes the line sv.grabURLInTheBackground ; and before it executes the requestDone or requestWentWrong methods, it executes the NSLog (NSLog(#"This line is executed "); )
What i want my program to do is to complete all the operations in the SendToServer NSObject class and then Execute the NSLog (In a sequence).
First execute sv.grabURLInTheBackground ; once all the activities in that method/class is over, then return to the code and execute the other line which is NSLog(#"This line is executed "); .
2.) I need to return a String when the requestDone method is executed. How do i modify the code to do so;
- (NSString * )requestDone:(ASIHTTPRequest *)request {
}
but how do i edit [request setDidFinishSelector:#selector(requestDone:)];, for the above code ?
------------------------------------------------------------------------------------------------------------------------------------------
EDIT
I am doing this for user login. Upon button click i will be calling the grabURLInTheBackground method from the NSObject class. And the viewcontroller needs to know if the user login was successful or failed.
SendToServer *sv = [[SendToServer alloc]];
[sv grabURLInTheBackground] ;
NSLog(#"User login SUcess or failed %#", [sv userloginSucessOrFail]);
For example say [sv userloginSucessOrFail] returns if the user login was success or failed.
What hapence here, is that after [sv grabURLInTheBackground] is called, it directly goes and executes the NSLog(#"User login SUcess or failed %#", [sv userloginSucessOrFail]); line of code.
What i want is, i need to find a way to let my ViewCOntroller know if the user login was a Success or failure.
First: call init on your object.
Second: grabURLInTheBackground is a method not a property. It should by called with square brackets
So you code becomes:
SendToServer *sv = [[SendToServer alloc] init];
[sv grabURLInTheBackground];
NSLog(#"This line is executed ");
To accomplish point 1) you need to make a synchronous request
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
}
The problem is that if this code is executed on the main thread is blocking (not good)...
For the second point. You can't.
EDIT:
What you have to do is something like the following steps:
Before calling grabURLInTheBackground you have to notify the user that a request is pending.. like putting an UIActivityIndicator, or disabling the UI,...
when you receive the callback then update the UI: hide the activity indicator, re-enable the UI... or if the request failed, notify the user.

Converting from ASIHTTPRequest to AFNetworking

I am converting my app routines from ASIHTTP to AFNetworking due to the unfortunate discontinuation of work on that project ... and what I found out later to be the much better and smaller codebase of AFNetworking.
I am finding several issues. My code for ASIHTTPRequest is built as a method. This method takes a few parameters and posts the parameters to a url ... returning the resulting data. This data is always text, but in the interests of making a generic method, may sometimes be json, sometimes XML or sometimes HTML. Thus I built this method as a standalone generic URL downloader.
My issue is that when the routine is called I have to wait for a response. I know all the "synchronous is bad" arguments out there...and I don't do it a lot... but for some methods I want synchronous.
So, here is my question. My simplified ASIHTTP code is below, followed by the only way i could think of coding this in AFNetworking. The issue I have is that the AFNetworking sometimes does not for the response before returning from the method. The hint that #mattt gave of [operation waitUntilFinished] totally fails to hold the thread until the completion block is called... and my other method of [queue waitUntilAllOperationsAreFinished] does not necessarily always work either (and does NOT result in triggering the error portion of the [operation hasAcceptableStatusCode] clause). So, if anyone can help, WITHOUT The ever-present 'design it asynchronously', please do.
ASIHTTP version:
- (NSString *) queryChatSystem:(NSMutableDictionary *) theDict
{
NSString *response = [NSString stringWithString:#""];
NSString *theUrlString = [NSString stringWithFormat:#"%#%#",kDataDomain,kPathToChatScript];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:theUrlString]];
for (id key in theDict)
{
[request setPostValue:[theDict objectForKey:key] forKey:key];
}
[request setNumberOfTimesToRetryOnTimeout:3];
[request setAllowCompressedResponse:YES];
[request startSynchronous];
NSError *error = [request error];
if (! error)
{
response = [request responseString];
}
return response;
}
AFNetworking version
- (NSString *) af_queryChatSystem:(NSMutableDictionary *) theDict
{
NSMutableDictionary *theParams = [NSMutableDictionary dictionaryWithCapacity:1];
for (id key in theDict)
{
[theParams setObject:[theDict objectForKey:key] forKey:key];
}
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:kDataDomain]];
NSMutableURLRequest *theRequest = [httpClient requestWithMethod:#"POST" path:[NSString stringWithFormat:#"/%#",kPathToChatScript] parameters:theParams];
__block NSString *responseString = [NSString stringWithString:#""];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:theRequest] autorelease];
operation.completionBlock = ^ {
if ([operation hasAcceptableStatusCode]) {
responseString = [operation responseString];
NSLog(#"hasAcceptableStatusCode: %#",responseString);
}
else
{
NSLog(#"[Error]: (%# %#) %#", [operation.request HTTPMethod], [[operation.request URL] relativePath], operation.error);
}
};
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation:operation];
[queue waitUntilAllOperationsAreFinished];
[httpClient release];
return responseString;
}
Thanks very much for any ideas.
- (void)af_queryChatSystem:(NSMutableDictionary *) theDict block:(void (^)(NSString *string))block {
...
}
Now within the completionBlock do:
block(operation.responseString);
block will act as the delegate for the operation. remove
-waitUntilAllOperationsAreFinished
and
return responseString
You call this like:
[YourInstance af_queryChatSystem:Dict block:^(NSString *string) {
// use string here
}];
Hope it helps. You can refer to the iOS example AFNetworking has
I strongly recommend to use this opportunity to convert to Apple's own NSURLConnection, rather than adopt yet another third party API. In this way you can be sure it won't be discontinued. I have found that the additional work required to get it to work is minimal - but it turns out to be much more robust and less error prone.
My solution is manually to run the current thread runloop until the callback have been processed.
Here is my code.
- (void)testRequest
{
MyHTTPClient* api = [MyHTTPClient sharedInstance]; // subclass of AFHTTPClient
NSDictionary* parameters = [NSDictionary dictionary]; // add query parameters to this dict.
__block int status = 0;
AFJSONRequestOperation* request = [api getPath:#"path/to/test"
parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// success code
status = 1;
NSLog(#"succeeded");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// failure
status = 2;
NSLog(#"failed");
}];
[api enqueueHTTPRequestOperation:request];
[api.operationQueue waitUntilAllOperationsAreFinished];
while (status == 0)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate date]];
}
STAssertEquals(status, 1, #"success block was executed");
}

NSURLRequest converting NSData to an array

I need to convert data received from the web via an array in a PHP script into an array that I can pull values out of. Here's my code!
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
//NSString *payloadAsString = [NSString stringWithUTF8String:[receivedData bytes]];
NSArray *payloadAsString = [NSKeyedUnarchiver unarchiveObjectWithData:receivedData];
[payloadAsString finishEncoding];
verified = [payloadAsString objectAtIndex:0];
NSLog(#"logging");
//NSString *no = [[NSString alloc] init stringWithCString:verified];
NSLog(#"%#", verified);
if([verified isEqualToString:#"admin"]){
NSLog(#"test admin");
[self performSelector:#selector(changeViewAdmin) withObject:nil afterDelay:0.05];
}
if([verified isEqualToString:#"user"]){
NSLog(#"test user");
[self performSelector:#selector(changeView) withObject:nil afterDelay:0.05];
}
if([verified isEqualToString:#"No"]){
NSLog(#"test no");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Invalid UserName/Password combination!"
delegate:self
cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[payloadAsString release];
//NSLog(#"%#", verified);
// INSERT GOOGLE MAPS URL REQUEST HERE
/*if(requestType == 1){
NSString* addressText = payloadAsString;
// URL encode the spaces
addressText = [addressText stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding];
NSString* urlText = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%#", addressText];
// lets throw this text on the log so we can view the url in the event we have an issue
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlText]];
// */
//
//}
[connection release];
self.receivedData = nil;
}
Unfortunately, my console returns null and asks if I've put the -finishencoding method in. Question is, if that's correct, where would I do so?
PS: Another question, is if I'm retrieving an array of data from a database, is a PHP script the best way to go? Thank you.
1) Of all this code the only string relevant to your question is
NSArray *payloadAsString = [NSKeyedUnarchiver unarchiveObjectWithData:receivedData];
I really doubt that PHP script returns you data in NSKeyedUnarchiver-compatible format. I believe the only reason you don't get NSInvalidArgumentException exception from this method is that receivedData is nil (did you initialize it anywhere?). Try to make a string from what you receive like this
[[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] autorelease]
and log it. From this I hope it will be clear how to parse response.
2) Do not name NSArray instances like 'blahBlahString'. Strings and arrays are completely different.
NSKeyedUnarchiver can only unarchive instances which are produced by instances of the NSKeyedArchiver class.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSKeyedUnarchiver_Class/index.html