Calling Webservice by NSURLConnection issues, Not called everytime? - http

I am calling .NET webservice hosted locally from my iPhone app (iOS5) like this:
(IBAction)btnCallService:(id)sender {
[XYZActivity startAnimating];
// So I could show activity on my main UI thread.
[self performSelector: #selector(CallXYZSService)
withObject: nil
afterDelay: 0];
}
(void) CallXYZSService
{
NSURL *url = [NSURL URLWithString: #"http://localwinhost/JSON_Service.asmx/GetFunction1"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:1 timeoutInterval:30];
NSData *requestData = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"close" forHTTPHeaderField:#"Connection"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: requestData];
//[req setHTTPBody: [postStr dataUsingEncoding:NSUTF8StringEncoding]];
myConn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (myConn) {
webData = [NSMutableData data];
}
else
{
NSLog(#"Connection Failed");
}
}
}
-(void) connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *) response{
[webData setLength: 0];
}
-(void) connection:(NSURLConnection *)connection
didReceiveData:(NSData *) data {
[webData appendData:data];
}
-(void) connection:(NSURLConnection *)connection
didFailWithError:(NSError *) error {
NSLog(#"Service Failed");
}
Now my problem is sometimes it calls the service and I recive data , and sometimes it doesn'tand nothing happens.... not even timeout error...
What I am doing wrong here , I am calling my webservice asynch ... issue is it even doesn't go to any other delegate methods , just prepare the request , init the connection and then nothing happens....
Is it has something to do with previous connections to the webservice ? As for testing I am calling 2,3 different functions on same service on same server ... but these are happening on different viewcontrollers ...so I init new connection and set my connection to nil in connectionDidFinishLoading method.
Can any one plz help me here, how to make sure that I always get response back from service either valid response or some error.... or timeout....
If I test the same service on MAC in Safari , it always get called without any issue...!!!
Thanks,
Maverick
I have changed the code as below
I have changed the code as below NSString *jsonRequest_NE = [NSString stringWithFormat:#"ID=%#&Password=%#",strID,strPwd];
NSString *jsonRequest = [jsonRequest_NE stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"Request: %#", jsonRequest);
NSString *myURL = #"http://localwinhost/JSON_Service.asmx/GetFunction1";
NSString *fixedURL = [myURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
but still the same beahviour, sometime it works sometimes it just doesn't.....
I have searched alot...but still could't find proper solution...
any one plz help me hereeeeeeeeeeee !!!

Make sure you don't have any non-UFT8 characters in your jsonRequest variable.
Let me know how you managed it.

Related

How to update Core Data and maintain user-saved data?

I have an app on the App Store that uses Core Data and I want to make an update. I use a preloaded sqlite file to create the persistentStore. There are two entities in the model, one of which holds user-saved data.
My issue: I want to update the existing Core Data with a new preloaded sqlite, but preserve the user-saved data. Is there a way to merge the new data of the preloaded file with the user-saved data?
The model remains the same; I haven't added any new entities or attributes, so I don't think a migration is appropriate (I could be wrong).
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"CreatureData.sqlite"];
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"CreatureData" ofType:#"sqlite"]];
NSLog(#"JUST LOADED COREDATA SQLITE");
NSError* err = nil;
if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
NSLog(#"Oops, couldn't copy preloaded data");
}
} else {
NSLog(#"Core Data SQLITE already exists");
}
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
//abort();
}
return _persistentStoreCoordinator;
}
EDIT:
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"CreatureData.sqlite"];
NSURL *secondStoreURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"CreatureData" ofType:#"sqlite"]];
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"CreatureData" ofType:#"sqlite"]];
NSLog(#"JUST LOADED COREDATA SQLITE");
NSError* err = nil;
if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
NSLog(#"Oops, couldn't copy preloaded data");
}
}
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = #{NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES };
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:#"UserSavedData" URL:storeURL options:options error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:#"StaticTableData" URL:secondStoreURL options:options error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
Apple recommends that you separate static and user data, in this case into 2 persistent stores. You could do one of the following:
First and preferable option, you use a separate store for the user data. You need to update the data model to accommodate two stores, so it will be a lightweight migration.
You would then extract the user data on the first startup from the existing sqlite store and store them to your new dynamic store. You can then delete the old sqlite store.
Second option is to keep the current setup. On first run, copy your new file with a different name, then extract the user data from the old store and copy it to the new store. Then delete the old store.

Core Data Fetch is Returning Nothing

In this app, I am using an sqlite database that was created by another app. I can query the database using the Firefox SQLite Manager and see that what I am searching for does exist in the database. I have reduced my query to something very simple, but still get nothing returned in my NSFetchedResultsController.
Here is my code:
- (NSFetchedResultsController*) frc {
if (!frc_) {
#autoreleasepool {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:#"INDEX" inManagedObjectContext:[ManagedObjectContext moc]];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:15];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"lemma = 'dog'"];
[NSFetchedResultsController deleteCacheWithName:nil];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:#"lemma" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:[ManagedObjectContext moc]
sectionNameKeyPath:#"lemma"
cacheName:nil];
aFetchedResultsController.delegate = (id<NSFetchedResultsControllerDelegate>)self;
NSError *error = nil;
if (![aFetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved Error %#, %#", error, [error userInfo]);
abort();
}
self.frc = aFetchedResultsController;
}
}
return frc_;
}
There is an entity called "INDEX" in the data model. To confirm that the entity has the lemma property, I show the content of its lemma property, getting this:
po [[entity propertiesByName] objectForKey:#"lemma"]
(id) $3 = 0x1104f740 (<NSAttributeDescription: 0x1104f740>), name lemma, isOptional 1, isTransient 0, entity INDEX, renamingIdentifier lemma, validation predicates (
), warnings (
), versionHashModifier (null)
userInfo {
}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)
Examining the contents of the aFetchedResultsController immediately after the fetch (where it is assigned to self.frc) gives this:
po aFetchedResultsController
(NSFetchedResultsController *) $4 = 0x1105c5c0 <NSFetchedResultsController: 0x1105c5c0>
po [[aFetchedResultsController fetchedObjects] count]
(id) $1 = 0x00000000 <nil>
I suppose the problem here is something very basic, but I don't know what I am overlooking.
I found the answer at the Ray Wenderlich site. The problem is that the sqlite file must be moved from the application bundle to the application documents directory.
This is done by copying it form the bundle into the documents directory if it is not already there.
Here is the code for creating the persistent store coordinator:
- (NSPersistentStoreCoordinator *)pstore {
if (pstore_ != nil) {
return pstore_;
}
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"words.sqlite"];
NSURL *storeUrl = [NSURL fileURLWithPath: storePath];
// THIS IS THE KEY PIECE TO IMPORTING AN EXISTING SQLITE FILE:
// Put down default db if it doesn't already exist
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle]
pathForResource:#"words" ofType:#"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSError *error = nil;
pstore_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.mom];
if(![pstore_ addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeUrl options:options error:&error]) {
// Error for store creation should be handled in here
}
return pstore_;
}

POST XML request to 'REST' service url from iPhone

I m pretty much new to objective-C and strucked at a point.I have to POST XML request to rest service url and get the response from it .I m using NSMutableRequest.But couldn't see any response.Couldn't understand where I m going wrong ...
Request XML is like this:
<GetUserRequest xmlns="http://schemas.datacontract.org/2004/07/DModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ID>456789</ID>
<UserEmail>John#yahoo.com</UserEmail>
</GetUserRequest>
My url is like this : http://192.158.0.104:8732/IServices/GetXml
MY code goes like this :
NSString *urlString1=[NSString stringWithFormat:#"http://192.158.0.104:8732/IServices/GetXml"];
NSMutableURLRequest *request=[[[NSMutableURLRequest alloc] init]autorelease];
[request setURL:[NSURL URLWithString:urlString1]];
[request setHTTPMethod:#"POST"];
NSString *contentType=[NSString stringWithFormat:#"application/xml"];
[request addValue:contentType forHTTPHeaderField:#"Content-type"];
NSMutableData *postBody=[NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:#"<GetUserRequest xmlns=\"http://schemas.datacontract.org/2004/07/DModel\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"]dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:#"<ID>456789</ID>"]dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:#"<UserEmail>John#yahoo.com</UserEmail>"]dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:#"/GetUserRequest>"]dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postBody];
NSHTTPURLResponse *urlResponse=nil;
NSError *error=[[NSError alloc]init];
NSData *responseData=[NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
NSString *rss=[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding ];
NSlog(#"Response Code:%d",[urlResponse statusCode]);
if([urlResponse statusCode ]>=200 && [urlResponse statusCode]<300)
{
NSLog(#"Response:%#",rss);
}
But I couldnot see anything in active console...
Any help would be appreciated ...
That code looks poor to me and doesn't contain enough error checking ([NSURLConnection sendSynchronousRequest] can return nil when an error occurs). Modify the end to:
NSError *error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponse
error:&error];
if (responseData != nil)
{
NSString *rss = [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding ];
NSlog(#"Response Code:%d",[urlResponse statusCode]);
if([urlResponse statusCode ]>=200 && [urlResponse statusCode]<300)
{
NSLog(#"Response:%#",rss);
}
}
else
{
NSLog(#"Failed to send request: %#", [error localizedDescription]);
}

AFNetworking Expected content type "application/xml", "text/xml", text/plain

I am trying to log into google reader using AfNetworking AfHttpClient but I am getting this error that I can;t seem to figure out.
Below is my subclass of AFNetworking:
// main url endpoints
#define GOOGLE_ACCOUNTS_BASE_URL #"https://www.google.com/accounts/"
#implementation ADPGoogleLoginClient
+ (ADPGoogleLoginClient *)sharedClient {
static ADPGoogleLoginClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[ADPGoogleLoginClient alloc] initWithBaseURL:[NSURL URLWithString:GOOGLE_ACCOUNTS_BASE_URL]];
});
return _sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
[self registerHTTPOperationClass:[AFXMLRequestOperation class]];
// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[self setDefaultHeader:#"Content-type" value:#"text/plain"];
[self setDefaultHeader:#"Accept" value:#"text/plain"];
return self;
}
#end
And then I try to form a request by using the following code:
//set up request params
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
#"googlereader-ios-client", #"client",
[keychainCredentials objectForKey:(__bridge id)kSecAttrAccount], #"Email",
[keychainCredentials objectForKey:(__bridge id)kSecValueData], #"Passwd",
#"reader", #"service",
#"ipad", #"source", nil];
//make requests
[[ADPGoogleLoginClient sharedClient] getPath:#"ClientLogin"
parameters:params
success:^(AFHTTPRequestOperation *operation , id responseObject)
{
//parse out token and store in keychain
NSString* responseString = [operation responseString];
NSString* authToken = [[[responseString componentsSeparatedByString:#"\n"] objectAtIndex:2]
stringByReplacingOccurrencesOfString:#"Auth=" withString:#""];
keychainToken = [[KeychainItemWrapper alloc] initWithIdentifier:#"GReaderToken" accessGroup:nil];
[keychainToken setObject:authToken forKey:(__bridge id)kSecValueData];
loginSuccess();
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"There was an error logging into Reader - %#", [error localizedDescription]);
loginFailure(error);
}];
Im setting the default headers to
[self setDefaultHeader:#"Content-type" value:#"text/plain"];
[self setDefaultHeader:#"Accept" value:#"text/plain"];
so im not sure why it still thinks it is expecting xml?
You are setting the Content-Type header for the request, but the error you're seeing is from the response. In order for requests to be considered "successful", the content type needs to match up with expectations (so as to avoid trying to parse a JSON response when you expected XML).
In that same error code, it should have mentioned what content type it actually got back. If it is indeed XML, add that using AFXMLRequestOperation +addAcceptableContentTypes:, and everything should work just fine.
Hi Matt so I just got around to testing this. Looks like I was registering the wrong AF operation. I changed
[self registerHTTPOperationClass:[AFXMLRequestOperation class]];
to
[self registerHTTPOperationClass:[AFHTTPRequestOperation class]];
and all was good!

How? UITableViewCell with UIImageView asynchronously loaded via ASINetworkQueue

I'm trying to load some images in table cells asynchronously using ASINetworkQueue. I just can't figure it out and can't seem to find a good SIMPLE example.
The best I can find is this, but its just totally overkill and a little too complicated for me:
http://kosmaczewski.net/2009/03/08/asynchronous-loading-of-images-in-a-uitableview/
Does anyone else have any tips/solutions/code for doing this with the ASIHTTPRequest library?
Here's a class derived from UIImageView which I use, perhaps this will help you. (Actually I've simplified this a fair bit from what I use, but that was what you asked for!)
Header file, UIHTTPImageView.h:
#import "ASIHTTPRequest.h"
#interface UIHTTPImageView : UIImageView {
ASIHTTPRequest *request;
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
#end
and UIHTTPImageView.m:
#import "UIHTTPImageView.h"
#implementation UIHTTPImageView
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
[request setDelegate:nil];
[request cancel];
[request release];
request = [[ASIHTTPRequest requestWithURL:url] retain];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
if (placeholder)
self.image = placeholder;
[request setDelegate:self];
[request startAsynchronous];
}
- (void)dealloc {
[request setDelegate:nil];
[request cancel];
[request release];
[super dealloc];
}
- (void)requestFinished:(ASIHTTPRequest *)req
{
if (request.responseStatusCode != 200)
return;
self.image = [UIImage imageWithData:request.responseData];
}
#end

Resources