I want to connect with a web service from my iOS app. Previously my URL was http://<domain name>/mobilews/mobilews.asmx. Recently I changed to http://<domain name>/mobilewstest/mobilews.asmx
I have put my URL in info plist file. But after I changed this into new URL I cannot login to that.
NSString *urlString = [NSString stringWithFormat:#"%#%#",serverURL,[queryString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSHTTPURLResponse *response ;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
int statusCode = [((NSHTTPURLResponse *)response) statusCode];`
Here returnData become nill and statusCode is 0. But this urlString is successfully logged in to the web service when it gives in the browser.
NSURL *url = [NSURL URLWithString:#"YOUR URL HERE"];
NSError *connectionError = nil;
NSData *inData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:&connectionError];
NSInteger code = [connectionError code];
if (code != 0)
{
NSString *locDesc = [NSString stringWithString:[connectionError localizedDescription]];
NSString *locFail = [NSString stringWithString:[connectionError localizedFailureReason]];
NSLog(#"Error: %d %# %#", code, locDesc, locFail);
}
else if ([inData length] == 0)
{
NSLog(#"No data");
}
else{
NSData *resultData = [NSData dataWithContentsOfURL:url];
NSString *responseString = [[NSString alloc]initWithData:resultData encoding:NSUTF8StringEncoding];
}
I see you send a syncronous request... try this its more an easy approach.
Related
Be gladfull about any info about how to add client p12 certificate validation to this ssl pinning code. This is part of ssl pinning module for react-native.
#import "RNSslPinning.h"
#import "AFNetworking.h"
#interface RNSslPinning()
#property (nonatomic, strong) NSURLSessionConfiguration *sessionConfig;
#end
#implementation RNSslPinning
RCT_EXPORT_MODULE();
- (instancetype)init
{
self = [super init];
if (self) {
self.sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration];
self.sessionConfig.HTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
}
return self;
}
RCT_EXPORT_METHOD(getCookies: (NSURL *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
NSHTTPCookie *cookie;
NSHTTPCookieStorage* cookieJar = NSHTTPCookieStorage.sharedHTTPCookieStorage;
NSMutableDictionary* dictionary = #{}.mutableCopy;
for (cookie in [cookieJar cookiesForURL:url]) {
[dictionary setObject:cookie.value forKey:cookie.name];
}
if ([dictionary count] > 0){
resolve(dictionary);
}
else{
NSError *error = nil;
reject(#"no_cookies", #"There were no cookies", error);
}
}
RCT_EXPORT_METHOD(removeCookieByName: (NSString *)cookieName
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in cookieStorage.cookies) {
// [cookieStorage deleteCookie:each];
NSString * name = cookie.name;
if([cookieName isEqualToString:name]) {
[cookieStorage deleteCookie:cookie];
}
}
resolve(nil);
}
-(void)performRequest:(AFURLSessionManager*)manager obj:(NSDictionary *)obj request:(NSMutableURLRequest*) request callback:(RCTResponseSenderBlock) callback {
[[manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
NSString *bodyString = [[NSString alloc] initWithData: responseObject encoding:NSUTF8StringEncoding];
NSInteger statusCode = httpResp.statusCode;
if (!error) {
// if(obj[#"responseType"]){
NSString * responseType = obj[#"responseType"];
if ([responseType isEqualToString:#"base64"]){
NSString* base64String = [responseObject base64EncodedStringWithOptions:0];
callback(#[[NSNull null], #{
#"status": #(statusCode),
#"headers": httpResp.allHeaderFields,
#"data": base64String
}]);
}
else {
callback(#[[NSNull null], #{
#"status": #(statusCode),
#"headers": httpResp.allHeaderFields,
#"bodyString": bodyString ? bodyString : #""
}]);
}
} else if (error && error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey]) {
dispatch_async(dispatch_get_main_queue(), ^{
callback(#[#{
#"status": #(statusCode),
#"headers": httpResp.allHeaderFields,
#"bodyString": bodyString ? bodyString : #""
}, [NSNull null]]);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
callback(#[error.localizedDescription, [NSNull null]]);
});
}
}] resume];
}
-(void) setHeaders: (NSDictionary *)obj request:(NSMutableURLRequest*) request {
if (obj[#"headers"] && [obj[#"headers"] isKindOfClass:[NSDictionary class]]) {
NSMutableDictionary *m = [obj[#"headers"] mutableCopy];
for (NSString *key in [m allKeys]) {
if (![m[key] isKindOfClass:[NSString class]]) {
m[key] = [m[key] stringValue];
}
}
[request setAllHTTPHeaderFields:m];
}
}
- (BOOL) isFilePart: (NSArray*)part {
if (![part[1] isKindOfClass:[NSDictionary class]]) {
return NO;
}
NSDictionary * value = part[1];
return [value objectForKey:#"type"] && ([value objectForKey:#"name"] || [value objectForKey:#"fileName"]);
}
-(void) appendFormDataFilePart: (id<AFMultipartFormData>) formData fileData: (NSArray*) fileData {
NSString * key = fileData[0];
NSDictionary * value = fileData[1];
NSString * fileName = [value objectForKey:#"name"] ? [value objectForKey:#"name"] : [value objectForKey:#"fileName"];
NSString * mimeType = [value objectForKey:#"type"];
NSString * path = [value objectForKey:#"uri"] ? [value objectForKey:#"uri"] : [value objectForKey:#"path"];
[formData appendPartWithFileURL:[NSURL URLWithString:path] name:key fileName:fileName mimeType:mimeType error:nil];
}
-(void) performMultipartRequest: (AFURLSessionManager*)manager obj:(NSDictionary *)obj url:(NSString *)url request:(NSMutableURLRequest*) request callback:(RCTResponseSenderBlock) callback formData:(NSDictionary*) formData {
NSString * method = obj[#"method"] ? obj[#"method"] : #"POST";
NSMutableURLRequest *formDataRequest = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:method URLString:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _formData) {
if([formData objectForKey:#"_parts"]){
NSArray * parts = formData[#"_parts"];
for (int i = 0; i < [parts count]; i++)
{
NSArray * part = parts[i];
NSString * key = part[0];
if ([self isFilePart:part]) {
[self appendFormDataFilePart:_formData fileData: part];
} else {
NSString * value = part[1];
NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
[_formData appendPartWithFormData:data name: key];
}
}
}
} error:nil];
// Migrate header fields.
[formDataRequest setAllHTTPHeaderFields:[request allHTTPHeaderFields]];
NSURLSessionUploadTask *uploadTask = [manager
uploadTaskWithStreamedRequest:formDataRequest
progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(#"Upload progress %lld", uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
}
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
NSString *bodyString = [[NSString alloc] initWithData: responseObject encoding:NSUTF8StringEncoding];
NSInteger statusCode = httpResp.statusCode;
if (!error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
NSString *bodyString = [[NSString alloc] initWithData: responseObject encoding:NSUTF8StringEncoding];
NSInteger statusCode = httpResp.statusCode;
NSDictionary *res = #{
#"status": #(statusCode),
#"headers": httpResp.allHeaderFields,
#"bodyString": bodyString ? bodyString : #""
};
callback(#[[NSNull null], res]);
}
else if (error && error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey]) {
dispatch_async(dispatch_get_main_queue(), ^{
callback(#[#{
#"status": #(statusCode),
#"headers": httpResp.allHeaderFields,
#"bodyString": bodyString ? bodyString : #""
}, [NSNull null]]);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
callback(#[error.localizedDescription, [NSNull null]]);
});
}
}];
[uploadTask resume];
}
RCT_EXPORT_METHOD(fetch:(NSString *)url obj:(NSDictionary *)obj callback:(RCTResponseSenderBlock)callback) {
NSURL *u = [NSURL URLWithString:url];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:u];
AFSecurityPolicy *policy;
BOOL pkPinning = [[obj objectForKey:#"pkPinning"] boolValue];
BOOL disableAllSecurity = [[obj objectForKey:#"disableAllSecurity"] boolValue];
NSSet *certificates = [AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]];
// set policy (ssl pinning)
if(disableAllSecurity){
policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
policy.validatesDomainName = false;
policy.allowInvalidCertificates = true;
}
else if (pkPinning){
policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:certificates];
}
else{
policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:certificates];
}
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.securityPolicy = policy;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
if (obj[#"method"]) {
[request setHTTPMethod:obj[#"method"]];
}
if (obj[#"timeoutInterval"]) {
[request setTimeoutInterval:[obj[#"timeoutInterval"] doubleValue] / 1000];
}
if(obj[#"headers"]) {
[self setHeaders:obj request:request];
}
if (obj) {
if ([obj objectForKey:#"body"]) {
NSDictionary * body = obj[#"body"];
// this is a multipart form data request
if([body isKindOfClass:[NSDictionary class]]){
// post multipart
if ([body objectForKey:#"formData"]) {
[self performMultipartRequest:manager obj:obj url:url request:request callback:callback formData:body[#"formData"]];
} else if ([body objectForKey:#"_parts"]) {
[self performMultipartRequest:manager obj:obj url:url request:request callback:callback formData:body];
}
}
else {
// post a string
NSData *data = [obj[#"body"] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
[self performRequest:manager obj:obj request:request callback:callback ];
//TODO: if no body
}
}
else {
[self performRequest:manager obj:obj request:request callback:callback ];
}
}
else {
}
}
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
#end
All info, I've had found, is about to create some challenge to session and send client certificate with password from there.
But not sure how to implement this right way. And can't figure which version of AFNetworking used in this SSL Pinning module.
Here is the answer.
In "fetch" function, after "manager" decloration, use this code:
[manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential *__autoreleasing _Nullable * _Nullable credential) {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustResultType result;
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);
// If we want to ignore invalid server for certificates, we just accept the server
if (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified) {
// When testing this against a trusted server I got kSecTrustResultUnspecified every time. But the other two match the description of a trusted server
*credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
}
return NSURLSessionAuthChallengeUseCredential;
}
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
SecIdentityRef identity = NULL;
SecTrustRef trust = NULL;
NSString *p12 = [[NSBundle mainBundle] pathForResource:#"client"ofType:#"p12"]; //client cert
NSData *PKCS12Data = [NSData dataWithContentsOfFile:p12];
OSStatus securityError = errSecSuccess;
NSDictionary*optionsDictionary = [NSDictionary dictionaryWithObject:#"password" forKey:(__bridge id)kSecImportExportPassphrase]; //client cert password
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import((__bridge CFDataRef)PKCS12Data,(__bridge CFDictionaryRef)optionsDictionary,&items);
if(securityError == 0) {
CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items,0);
const void*tempIdentity =NULL;
tempIdentity= CFDictionaryGetValue (myIdentityAndTrust,kSecImportItemIdentity);
identity = (SecIdentityRef)tempIdentity;
const void*tempTrust =NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust);
trust = (SecTrustRef)tempTrust;
}
SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate(identity, &certificate);
const void*certs[] = {certificate};
CFArrayRef certArray =CFArrayCreate(kCFAllocatorDefault, certs,1,NULL);
*credential =[NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];
return NSURLSessionAuthChallengeUseCredential;
}
return NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}];
I tried to translate part of the objective-c but I still stuck at part of them
any idea ? Thanks so much
objective c version
if ([FBSDKAccessToken currentAccessToken]) {
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:#"picture",#"fields",nil];
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"me"
parameters:params
HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
UIImage * downloadedImage = [UIImage imageWithData:pictureData];
dispatch_async(dispatch_get_main_queue(), ^{
self.profilePictureImageView.image = downloadedImage;
});
}];
}
ruby motion version
if (FBSDKAccessToken.currentAccessToken) {
request = FBSDKGraphRequest.alloc.initWithGraphPath("me", parameters:nil, HTTPMethod: "GET")
}
Finally, I came up with the corresponding code in rubymotion
Please correct me directly if anything wrong, it works for me now
part of original objective-c
if ([FBSDKAccessToken currentAccessToken]) {
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"me"
parameters:params
HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
}];
}
convert version by ruby_motion_query
def loginButton(loginButton, didCompleteWithResult: result, error: error)
puts result
puts error
if not error
request = FBSDKGraphRequest.alloc.initWithGraphPath("me", parameters:nil, HTTPMethod: "GET")
request.startWithCompletionHandler( lambda{ |connection, user, error|
#DO_ANYTHING_YOU_WANT_FATE_LOGINING_SUCESSFULLY
rmq(#fb_login_button).animate { |btn| btn.move(b: 400) }
#name_label = rmq.append(UILabel, :label_name).get
#name_label.text = "#{user['first_name']} #{user['last_name']}"
rmq(#name_label).animations.fade_in
})
end
end
def loginButtonDidLogOut(loginButton)
#DO_ANYTHING_YOU_WANT_HERE
end
I am trying to fetch a XML file from a URL and store it locally, yet I find the [NSData dataWithContentsOfURL xxxx] returns nil to me.
The error message reads: operation couldn’t be completed. (Cocoa error 256.)
Could you help to review my code and point to me the problem:
NSError* err = nil;
NSString* urlString = #"http://www.w3school.com.cn/example/xmle/note.xml";
NSURL* xmlUrl = [NSURL URLWithString:urlString];
NSData* xmlData = [NSData dataWithContentsOfURL:xmlUrl options: NSDataReadingUncached error: &err];
I'm trying to make post with more than a photo in Fb using batch request but I keep getting timeout errors from Fb server...
This is my code ..
UIImage *imgFile1 = [UIImage imageNamed:#"iTGps.png"];
NSData *imageData = UIImageJPEGRepresentation(imgFile1, 0.5);
NSString *jsP1 = [NSString stringWithFormat:#"{ \"method\": \"POST\", \"relative_url\": \"me/photos\",\"body\":\"message=My cat photo\",\"attached_files\":\"%#\"}",imageData];
NSString *jsonRequestsArray = [NSString stringWithFormat:#"[%#,%#,%#]",jsP1,jsP1,jsP1];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObject:jsonRequestsArray forKey:#"batch"];
FBRequestConnection *connect = [[FBRequestConnection alloc] initWithTimeout:60];
// do Fb request
FBRequest *request = [FBRequest requestWithGraphPath:#"me/photos"
parameters:params
HTTPMethod:#"POST"];
// add connection
[connect addRequest:request
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
NSLog(#"Result:%#,%#",result,error);
}];
[connect start];
Where am I doing wrong??
Error code is very long so i cut the middle part (i think is the binary images)
2013-04-28 20:03:32.435 trueGps[1887:1a603] Result:(null),Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0x14454010 {com.facebook.sdk:ErrorInnerErrorKey=Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x14492d40 {NSErrorFailingURLStringKey=https://graph.facebook.com/me/photos?sdk=ios&batch=%5B%7B%20%22method%22%3A%20%22POST%22%2C%20%22relative_url%22%3A%20%22me%2Fphotos%22%2C%22body%22%3A%22message%3DMy%20cat%20photo%22%2C%22attached_files ....
NSLocalizedDescription=The request timed out., NSUnderlyingError=0x2a90f620 "The request timed out."}, com.facebook.sdk:HTTPStatusCode=200}
i solve the problem .. but still have more post with only a photo in every one..
NSString *rel_url = [NSString stringWithFormat:#"%#/photos",nomeAlbum];
NSString *jsP1 = [NSString stringWithFormat:#"{ \"method\": \"POST\", \"relative_url\": \"%#\", \"body\": \"message=My_cat_photo\", \"attached_files\": \"file1\" }",rel_url];
NSString *jsonRequestsArray = [NSString stringWithFormat:#"[%#]",jsP1];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObject:jsonRequestsArray forKey:#"batch"];
[params setObject:imgFile1 forKey:#"file1"];
[FBRequestConnection startWithGraphPath:rel_url
parameters:postParams
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
}];
I need to send RestFul Web Service Request with post type ,post data format is like as below {"Request":"parameters".... }and binary data with same request.Is it possible with ios if possible means explain please?
I don't recommend using the ASIHttpRequest library anymore because it's not getting any updates from the developer , as to how to create a post http request here's an example
NSString *url = #"your webservice base url";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
NSString *param2 = ...//
NSData *binaryData = .... //initilize the binary data you want to send
NSString *bodyString = [NSString stringWithFormat:#"param1=%#¶m2=%#",binartData,param2];
[request setValue:[NSString stringWithFormat:#"%d", [bodyString length]] forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[bodyString dataUsingEncoding:NSASCIIStringEncoding]];//or set the type of encoding agreed with your webservice
NSURLResponse *response = nil;
NSError *error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *responseString;
if ( responseData && !error){
responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
}