I am developing an application in which I am doing XML parsing. I found an error in the [xmlparse parse] method.
Error:
[NSCFString bytes]: unrecognized selector sent to instance 0x3df6310
2010-04-30 00:09:46.302 SPCiphone2[4234:1003] void SendDelegateMessage
(NSInvocation*): delegate (<CFNotificationCenter 0x3d09670 [0x87dca0]>)
failed to return after waiting 10 seconds. main run loop mode:
kCFRunLoopDefaultMode
Code snippet:
responseOfWebResultData = [[NSMutableString alloc]
initWithData:responseData
encoding:NSUTF8StringEncoding];
NSLog(#"result: %#", responseOfWebResultData);
// starting the XML parsing
if (responseOfWebResultData) {
#try {
xmlParser = [[NSXMLParser alloc] initWithData:responseOfWebResultData];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
[responseOfWebResultData release];
}
#catch (NSException *e) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Please"
message:[e reason]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
You should not be passing in a NSString* into initWithData:. You should do this:
xmlParser = [[NSXMLParser alloc] initWithData:responseData];
The error says that you're sending the message bytes to an instance of NSCFString, which is a NSString*, even though you declared it as a NSMutableString*, because this is a dynamically typed language but the class types are not automatically converted if you try to cast it to something else.
Related
i have write a NSDictionary Category. The Category has a method calls "initWithJSONURL".
Here the code:
- (id)initWithJSONURL:(NSURL *)url
{
self = [super init];
if (self) {
NSError *error;
NSData *data = [NSData dataWithContentsOfURL:url
options:NSUTF8StringEncoding
error:&error];
if (!data) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"connection failed"
message:[error localizedDescription]
delegate:self
cancelButtonTitle:#"cancel"
otherButtonTitles:nil];
[alert show];
} else {
self = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"invalid data"
message:[error localizedDescription]
delegate:self
cancelButtonTitle:#"cancel"
otherButtonTitles:nil];
[alert show];
}
}
}
return self;
}
And here the code from my ViewController viewDidLoad
NSURL *url = [NSURL URLWithString:#"http://localhost:8888/json.php"];
NSDictionary *dict = [[NSDictionary alloc] initWithJSONURL:url];
NSLog(#"%#", dict);
If I use an correct URL everything works perfect.
But if the URL not correct, the App crash.
I don't know why, it should not crash, it should show the alert View.
The consoles show:
erminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSDictionary count]: method sent to an uninitialized immutable dictionary object'
I hope anybody can help me and sorry for my bad english.
You want to call [self init] instead of [super init]. A category is not a subclass, so [super init] means [NSObject init]. The designated initializer of NSDictionary is never called and the internal dictionary structures are staying unitiliazed.
I'm taking xml response from service url and I want to display error, when network connection fails. So I display the UIAlertView, but this alertView is getting displayed after the rest of process is completed. I want it to be shown immediately.
In android, if network connection fails, it will display an error alert that "Unfortunately app name has terminated". Is there anything of such for iPhone? If not I want to show alertview and stop the rest of the process.
This is the code I'm working on:
if (responseData!= NULL)
{
response = [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding ];
NSLog(#"Response Code:%d",[urlResponse statusCode]);
if([urlResponse statusCode ]>=200 && [urlResponse statusCode]<300)
{
NSLog(#"Response:%#",response);
}
}
else
{
NSLog(#"Failed to send request: %#", [error localizedDescription]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Unfornately stopped.Try Again " message:#"" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
parser =[[NSXMLParser alloc]initWithData:responseData];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
currentHtmlElement=#"1";
[parser parse];
[parser release];
In my code if it fails to send request, then NSLog gets printed and alertView code is executed. At the same time I want to stop the rest of the process i.e initialising a parser and doing the rest of operation.
How can I do it?
Very simple... Move your parse code inside if block.
if (responseData!= NULL)
{
response = [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding ];
NSLog(#"Response Code:%d",[urlResponse statusCode]);
if([urlResponse statusCode ]>=200 && [urlResponse statusCode]<300)
{
NSLog(#"Response:%#",response);
}
parser =[[NSXMLParser alloc]initWithData:responseData];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
currentHtmlElement=#"1";
[parser parse];
[parser release];
}
else
{
NSLog(#"Failed to send request: %#", [error localizedDescription]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Unfornately iCloudBiz has stopped.Try Again " message:#"" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
By the way... You mentioned your Android's app behavior as follows
In android if network connection fails it will display an error alert that Unfortunatly app name has terminated.
Please understand that this behavior is an abnormal behavior. This is called a CRASH and you should handle this appropriately. If network is disconnected app should display a message without terminating/crashing :)
You should use Reachability class to check for whether internet connection is available or not
this is sample code to understand how it works
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
if (internetStatus != NotReachable) {
//my web-dependent code
}
else {
//there-is-no-connection warning
}
I have an error while reading XML files for my iPhone app. I have a new feature on my iPhone app that reads my RSS feed. Everything looks good by but I have this issue:
Error while loading rss. Please check your Internet connection
Here's my code:
- (BOOL) readRSS {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
BOOL success = NO;
NSXMLParser *parser = nil;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://rss.domain.com/%#.xml", self.currentPage]];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
success = [parser parse];
[parser release];
[pool drain];
return success;
}
Then I have this code:
- (void) cleartbl:(NSInteger)type {
[[[self rssParser] rssItems] removeAllObjects];
[_tableView reloadData];
if(type == 1) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"RSS Feed"
message:#"Error while loading rss. Please check your Internet connection."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
[alert release];
}
Then i assign:
if([elementName isEqualToString:#"title"]){
self.currentItem.title = self.currentItemValue;
}
What is my issue, am I missing something?
The code provided looks good for me, what I would do first is to check if your RSS is valid. I think you have an RSS issue here. You can use the RSS Validation to make sure everything looks good.
I would recommend to sanitize your RSS, keep it very simple, if you only want to display news or articles use letters and numbers in your text and use SEO friendly URLs.
This will simplify the data you are loading from your app and avoid errors like special characters.
Try with a simple RSS with one entry to start and you will see if your code has errors.
I want to check the app version from apple so I send request like below
- (void)connectToCheckVersion{
NSString *url = #"http://itunes.apple.com/lookup?id=466424846";
TTURLRequest *_request = [TTURLRequest requestWithURL:url delegate:self];
_request.httpMethod = #"GET";
_request.cachePolicy = TTURLRequestCachePolicyNone;
_request.shouldHandleCookies = NO;
TTURLJSONResponse* response = [[TTURLJSONResponse alloc] init];
_request.response = response;
TT_RELEASE_SAFELY(response);
[_request send];
}
- (void)requestDidFinishLoad:(TTURLRequest*)request {
TTURLJSONResponse* response = request.response;
NSDictionary* json = response.rootObject;
NSArray *results = [json objectForKey:#"results"];
NSString *version;
for (NSDictionary *rawResult in results) {
version = [rawResult objectForKey:#"version"];
}
NSString *currentVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleShortVersionString"];
if (version != nil && currentVersion != nil && ![version isEqualToString:currentVersion]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"info"
message:#"newer version"
delegate:self
cancelButtonTitle:#"ok"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
and after [_request send]; will get [CFString release]: message sent to deallocated instance 0x6a83e00. I checked all Strings in this method seems they are ok, and I can still get correct response from remote.
If I comment out this connectToCheckVersion method then no any problem.
Any diea?
I think that you should retain the _request variable and save it as a member.
Because it will autorelease after the function is returned.
You have to release it after the request is successed or failed.
Thank you.
I try to add a method to handle exception, but the program just crashes instead of pop up an AlertView.
1) I set up the connection:
-(void)connect:(NSString *)strURL
{
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:strURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection)
{
// receivedData is declared as a method instance elsewhere
receivedData = [[NSMutableData data] retain];
}
else
{
// inform the user that the download could not be made
}
}
2)I add method to receive data and conver it to string:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// append the new data to the receivedData
// receivedData is declared as a method instance elsewhere
[receivedData appendData:data];
ReturnStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
3)I add exception handle method:
-(void) connection:(NSURLConnection *)connection didFailWithError: (NSError *)error {
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle: [error localizedDescription]
message: [error localizedFailureReason]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
}
After I change the strURL to a wrong url, the program just crashes. Any ideas why the AlertView doesn't pop up?
Check out the error handling that I've got in this file. If you set the URL to an invalid URL, it does (in my example) come back with a nice dialog error message. I just tried it to be sure.
Relevant code in the linked file is:
-(void) connection:(NSURLConnection *)connection
didFailWithError: (NSError *)error {
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle: [error localizedDescription]
message: [error localizedFailureReason]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
[activityIndicator stopAnimating];
NSLog (#"Connection Failed with Error");
}