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

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!

Related

Loading an audio sample from the documents folder

I'm trying to have an app play audio files added via itunes file-sharing. I've managed the app to retrieve the app's sandbox folder's content, but I'm not able to load such files into a C4Sample by specifying the complete path.
NSString *documentsFolder;
NSString *clickAudioPath;
C4Sample *clicksample;
-(void)setup {
// Retrieve the app's Documents folder
documentsFolder = [self applicationDocumentsDirectory];
clickAudioPath = [NSString stringWithFormat:#"%#/click.mp3", documentsFolder];
// Add test click audio
clicksample = [C4Sample sampleNamed:clickAudioPath];
[clicksample prepareToPlay];
[clicksample play];
}
// Get Documents folder
- (NSString *) applicationDocumentsDirectory{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
The above code doesn't play any sound, although I've doubled checked that clicksample actually refers to an existing file. How can I specify a complete path instead of just a name to load the audio?
Add a new method as below.
-(id) initWithURL:(NSURL *) soundFileURL
{
self = [super init];
if(self != nil) {
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
self.enableRate = YES;
self.player.delegate = self;
[self setup];
}
return self;
}

how to use FBTestSession with Setup call of unit test

I'm trying to set up my unit test to use the latest facebook SDK and am running into issues...
Here is the code i have:
[FBSession setDefaultAppID: #"323351877676429"];
FBTestSession *session = [FBTestSession sessionWithSharedUserWithPermissions: [NSArray array]];
STAssertNotNil(session, #"could not create test session");
[FBTestSession openActiveSessionWithReadPermissions:#[]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#"completed");
[FBSession setActiveSession: session];
STAssertNil(error, error.description);
STAssertNotNil(FBSession.activeSession, #"FBSession missing");
STAssertNotNil(FBSession.activeSession.accessTokenData, #"FBSession missing");
STAssertNotNil(FBSession.activeSession.accessTokenData.accessToken, #"facebook token is nil");
STAssertNotNil(session, #"FBSession missing");
STAssertNotNil(session.accessTokenData, #"FBSession missing");
STAssertNotNil(session.accessTokenData.accessToken, #"facebook token is nil");
userModel *userM = [[userModel alloc] init];
[userM awakeFromNib];
} ];
This works well except that as it runs asynchronously, when my test are run the session is not ready and thus i have session.accessTokenData == nil., which make my other test fail.
If i add the below code to my set up method after the openSession call, then the setup method never returns.
while (!FBSession.activeSession.accessTokenData)
[NSThread sleepForTimeInterval:.2];
Is there an exemple of proper use of FBTestSession somewhere? Any clue as to how to proceed?
Thanks, olivier
You are close, you just need to wait until the blocks are complete. Here is a working example (slightly shortened/modified) that you can use for reference.
- (void)testFacebookLogin {
__block bool blockFinished = NO;
FBTestSession *fbSession = [FBTestSession sessionWithSharedUserWithPermissions:#[#"email"]];
[fbSession openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#"session %#, status %d, error %#", session, status, error);
[FBSession setActiveSession:session];
FBRequest *me = [FBRequest requestForMe];
NSLog(#"me request %#", me);
[me startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *my,
NSError *error) {
STAssertNotNil(my.id, #"id shouldn't be nil");
blockFinished = YES;
}];
}];
// Run loop
NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:10];
while (blockFinished == NO && [loopUntil timeIntervalSinceNow] > 0) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:loopUntil];
}
}

get image from asyncimageview

I have a little problem, I use this class for load some image asincronusly
#import <UIKit/UIKit.h>
#interface AsyncImageView : UIView {
NSURLConnection* connection;
NSMutableData* data;
}
- (void)loadImageFromURL:(NSURL*)url;
- (UIImage*) image;
#end
#import "AsyncImageView.h"
#implementation AsyncImageView
- (void)dealloc {
[connection cancel]; //in case the URL is still downloading
}
- (void)loadImageFromURL:(NSURL*)url {
//in case we are downloading a 2nd image
NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; //notice how delegate set to self object
}
//the URL connection calls this repeatedly as data arrives
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
if (data==nil) { data = [[NSMutableData alloc] initWithCapacity:2048]; }
[data appendData:incrementalData];
}
//the URL connection calls this once all the data has downloaded
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
//so self data now has the complete image
connection=nil;
if ([[self subviews] count]>0) {
//then this must be another image, the old one is still in subviews
[[[self subviews] objectAtIndex:0] removeFromSuperview]; //so remove it (releases it also)
}
//make an image view for the image
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:data]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout];
[self setNeedsLayout];
data=nil;
}
- (UIImage*) image {
UIImageView* iv = [[self subviews] objectAtIndex:0];
return [iv image];
}
#end
and this for load the image
AsyncImageView *asyncImage = [[AsyncImageView alloc] initWithFrame:frame];
asyncImage.tag = 999;
NSURL *url = [NSURL URLWithString:indirizzoImmagine];
[asyncImage loadImageFromURL:url];
[self.view addSubView:asyncImage]
with this code all work but when I try to put asyncImage on [cell.imageview setImage:async.image]; the app crash, I think that I need to change the subclass in uiimageview but nothing...the same error
Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'
How can I geto only the image?
In AsyncImageView class synthesize imageCache using following code you can get the image
[imageView.imageCache imageForKey:str_ImgUrl];
Here imageView is the object of AsyncImageView.

Calling Webservice by NSURLConnection issues, Not called everytime?

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.

UILocalNotification nil userInfo

I try to cancel a Local notification. I attach a dict with a Id for locate it later:
+ (void) send:(NSString*)title actionText:(NSString *)actionText when:(NSDate *)when count:(NSInteger)count option:(NSDictionary *)options
{
UILocalNotification *notif = [[UILocalNotification alloc] init];
//Setup code here...
notif.userInfo = options;
ALog(#"Sending notification %# %#", notif.alertBody, notif.userInfo);
//Print: Sending notification Task Col 0 0 {id = "1-1"};
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
}
Then when I try to locate it:
+ (void) cancelNotification:(NSString *)theId {
for(UILocalNotification *aNotif in [[UIApplication sharedApplication] scheduledLocalNotifications])
{
if([[aNotif.userInfo objectForKey:#"id"] isEqualToString:theId])
{
// Never come here: userInfo is nil!!!
}
}
}
Always the userInfo is nil. I send the dict:
NSMutableDictionary *info = [[NSMutableDictionary alloc] init];
[info setObject:theId forKey:#"id"];
or
[NSMutableDictionary dictionaryWithObject:theId forKey:#"id"]
with the same result. (theId is NSString)
The local notification valid only, it has valid timestamp. So while you are creating make sure that, it has valid timestamp. So that, it will be present in scheduledNotifications of UIApplicaiton.
Please let me know your comments.
eg: localNotification.fireDate = [NSDate date];

Resources