I am using a NSURLConnect call and I get unsupported URL when I have a space in my query string. To fix this I converted the string to base64 and I am still getting errors. How do I send a base64 string though NSUrlConnect successfully? If this isn't possible, how do I safely send a string with a space in it?
NSData *convertData = [queryWS dataUsingEncoding: NSUnicodeStringEncoding];
queryWS = [convertData base64EncodedStringWithOptions:kNilOptions];
NSURLRequest *urlRequest =
[NSURLRequest requestWithURL:[NSURL URLWithString:queryWS]];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
if (!error) {
responseDictionary =
[NSJSONSerialization JSONObjectWithData:data
options:0
error:&parseError];
You do not want to convert the URL string to base64 encoding. What you want is to properly escape any special characters in the URL. Please see the NSString stringByAddingPercentEscapesUsingEncoding: method or NSString stringByAddingPercentEncodingWithAllowedCharacters: if you only need to support iOS 9 or later.
NSString *queryString = #"SOME_QUERY_STRING";
NSString *encodedQueryString = [queryString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
I have a URL like so ANC & SHO.pdf
when I encode the URL like so:
NSString *escapedString = [PDFPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
now when I use this URL it does not work and I have a feeling it has to do with the & because when I tried another file, it worked perfectly I was able to load the PDF, but with the file with & I was not.
What Am I doing wrong?
Here is the output of escapedString
escapedString __NSCFString * #"Ancaster%5CANC%20&%20SHO%20-%20Laundry%20Closets%20to%20be%20Checked.pdf" 0x16ea33c0
I then use that to call a method:
NSArray *byteArray = [dataSource.areaData GetPDFFileData:[NSString stringWithFormat:#"%#",escapedString]];
Here is the method:
-(NSArray *)GetPDFFileData:(NSString *)PDFFile
{
NSString *FileBrowserRequestString = [NSString stringWithFormat:#"%#?PDFFile=%#",kIP,PDFFile];
NSURL *JSONURL = [NSURL URLWithString:FileBrowserRequestString];
NSURLResponse* response = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
if(data == nil)
return nil;
NSError *myError;
NSArray *tableArray = [[NSArray alloc]initWithArray:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
return tableArray;
}
[NSCharacterSet URLHostAllowedCharacterSet] contains characters below:
!$&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~
which contains '&', so
NSString *escapedString = [PDFPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
won't escape '&' for you, then it's not URLEncoded.
see the question about how to url encode a string.
Try to pass my NSString to a URLWithString but no url appear:
//here i get my url from my API and replacing tags
NSString *queryContent = [[[(webLinks)[#"content"] stringByReplacingOccurrencesOfString:#"&" withString:#"&"]
stringByReplacingOccurrencesOfString:#"<p>" withString:#""]
stringByReplacingOccurrencesOfString:#"</p>" withString:#""];
//here i get the full url
NSURL * url = [NSURL URLWithString:queryContent];
Adding a NSLogs:
NSLog(#"query:%#", queryContent);
NSLog(#"website:%#", url);
and the result is this:
query:http://mywebsite.com
website:(null)
Whats wrong?
thanks
//SOLVED//
here the correct code if any of you use my same system JSON API for WordPress:
NSRange r;
NSString *queryUrl = [(webLinks)[#"content"] stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *website = queryUrl;
while ((r = [website rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
website = [website stringByReplacingCharactersInRange:r withString:#""];
NSURL * url = [NSURL URLWithString:website];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
I have to integrate PayUMoney payment gateway in my iOS app. They don't have SDK for iOS. So I have to load some web URL in webview for the payment. My parameters are
int i = arc4random() % 9999999999;
NSString *strHash = [self createSHA512:[NSString stringWithFormat:#"%d%#",i,[NSDate date]]];// Generatehash512(rnd.ToString() + DateTime.Now);
NSString *txnid1 = [strHash substringToIndex:20];
NSLog(#"tnx1 id %#",txnid1);
NSString *key = #"JBZaLc";
NSString *amount = #"1000";
NSString *productInfo = #"Nice product";
NSString *firstname = #"Mani";
NSString *email = #"mani.ingenius#gmail.com";
NSString *phone = #"1234566";
NSString *surl = #"www.google.com";
NSString *furl = #"www.google.com";
NSString *serviceprovider = #"payu_paisa";
NSString *action = #"https://test.payu.in/_payment";
NSString *hashValue = [NSString stringWithFormat:#"%#|%#|%#|%#|%#|%#|udf1|udf2|udf3|udf4|udf5||||||salt",key,txnid1,amount,productInfo,firstname,email];
NSString *hash = [self createSHA512:hashValue];
NSDictionary *parameters = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:txnid1,key,amount,productInfo,firstname,email,phone,surl,furl,hash,serviceprovider,action, nil] forKeys:[NSArray arrayWithObjects:#"txnid",#"key",#"amount",#"productinfo",#"firstname",#"email",#"phone",#"surl",#"furl",#"hash",#"service_provider",#"action", nil]];
I have to use POST method with my test URL (https://test.payu.in/_payment) and need to pass parameters. I have all parameters with key and value in dictionary("parameters"). So I tried following code
NSData *dataValue = [self getPropertiesAsData:parameters];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"https://test.payu.in/_payment"]];
// Create a mutable copy of the immutable request and add more headers
NSMutableURLRequest *mutableRequest = [request mutableCopy];
[mutableRequest setHTTPMethod: #"POST"];
[mutableRequest setHTTPBody: dataValue];
request = [mutableRequest copy];
[_webviewSample loadRequest:request];
-(NSData *)getPropertiesAsData :(NSDictionary *)dict{
NSMutableData *body = [NSMutableData postData];
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[body addValue:[obj stringByReplacingOccurrencesOfString:#" " withString:#"%20"] forKey:key];
}];
return body;
}
-(NSString *)createSHA512:(NSString *)string
{
const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:string.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x", digest[i]];
return output;
}
But when I run this, it says "Mandatory parameter tnxid is missing". But I have passed the tnxid which you can see in parameters dictionary. If I pass everything correctly then result will be the webpage where user can select bank details, etc that I have to load it in my web view.
Please help me to find what I did wrong or what I should do to get correct result.
I found answer successfully. My working code is listed below
int i = arc4random() % 9999999999;
NSString *strHash = [self createSHA512:[NSString stringWithFormat:#"%d%#",i,[NSDate date]]];// Generatehash512(rnd.ToString() + DateTime.Now);
NSString *txnid1 = [strHash substringToIndex:20];
NSLog(#"tnx1 id %#",txnid1);
NSString *key = #"JBZaLc";
NSString *amount = #"1000";
NSString *productInfo = #"Nice product";
NSString *firstname = #"Mani";
NSString *email = #"mani.ingenius#gmail.com";
NSString *phone = #"1234566";
NSString *surl = #"www.google.com";
NSString *furl = #"www.google.com";
NSString *serviceprovider = #"payu_paisa";
NSString *hashValue = [NSString stringWithFormat:#"%#|%#|%#|%#|%#|%#|||||||||||GQs7yium",key,txnid1,amount,productInfo,firstname,email];
NSString *hash = [self createSHA512:hashValue];
NSDictionary *parameters = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:txnid1,key,amount,productInfo,firstname,email,phone,surl,furl,hash,serviceprovider
, nil] forKeys:[NSArray arrayWithObjects:#"txnid",#"key",#"amount",#"productinfo",#"firstname",#"email",#"phone",#"surl",#"furl",#"hash",#"service_provider", nil]];
__block NSString *post = #"";
[parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([post isEqualToString:#""]) {
post = [NSString stringWithFormat:#"%#=%#",key,obj];
}else{
post = [NSString stringWithFormat:#"%#&%#=%#",post,key,obj];
}
}];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://test.payu.in/_payment"]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
[_webviewSample loadRequest:request];
then functions to be used
-(NSString *)createSHA512:(NSString *)string
{
const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:string.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x", digest[i]];
return output;
}
Finally i resolved the issue regarding PayU India (not payU,payU and payUindia have a slight difference as mention) integration (above code is for payU Money help alot)
Download github Repo here
You only need to remove an extra parameter which is service_provider whose value is payu_paisa.
int i = arc4random() % 9999999999;
NSString *strHash = [self createSHA512:[NSString stringWithFormat:#"%d%#",i,[NSDate date]]];// Generatehash512(rnd.ToString() + DateTime.Now);
NSString *txnid1 = [strHash substringToIndex:20];
NSLog(#"tnx1 id %#",txnid1);
NSString *key = #"YOURKEY";
NSString *salt = #"YOURSALTKEY";
NSString *amount = #"100";
NSString *productInfo = #"Niceproduct";
NSString *firstname = #"Deepak";
NSString *email = #"iphonemaclover#gmail.com";
NSString *phone = #"9212138007";
NSString *surl = #"www.google.com";
NSString *furl = #"www.google.com";
NSString *hashValue = [NSString stringWithFormat:#"%#|%#|%#|%#|%#|%#|||||||||||%#",key,txnid1,amount,productInfo,firstname,email,salt];
NSString *hash = [self createSHA512:hashValue];
NSDictionary *parameters = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:txnid1,key,amount,productInfo,firstname,email,phone,surl,furl,hash
, nil] forKeys:[NSArray arrayWithObjects:#"txnid",#"key",#"amount",#"productinfo",#"firstname",#"email",#"phone",#"surl",#"furl",#"hash", nil]];
__block NSString *post = #"";
[parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([post isEqualToString:#""]) {
post = [NSString stringWithFormat:#"%#=%#",key,obj];
}else{
post = [NSString stringWithFormat:#"%#&%#=%#",post,key,obj];
}
}];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://test.payu.in/_payment"]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
[_webviewSample loadRequest:request];
EDIT: how to handle URL payment is sucess or not
-(void)webViewDidFinishLoad:(UIWebView *)webView{
if (web_view_PayU.isLoading)
return;
NSURL *requestURL = [[web_view_PayU request] URL];
NSLog(#"requestURL=%#",requestURL);
NSString *getStringFromUrl=[NSString stringWithFormat:#"%#",requestURL];
if ([getStringFromUrl isEqualToString:#"https://test.payu.in/yoursucessurladdedhere "]||[getStringFromUrl isEqualToString:#"https://secure.payu.in/yoursucessurladdedhere "])
{
//SUCCESS ALERT
//jump to place order API
}
else if ([getStringFromUrl isEqualToString:#"https://test.payu.in/yourfailureurladdedhere "]||[getStringFromUrl isEqualToString:#"https://secure.payu.in/yourfailureurladdedhere"])
{
// FAIL ALERT
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Sorry!" message:#"Your Order Not Successfull!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
alert.tag=2222;
[alert show];
}
}
For Android Integration of Pay U check link--
I mailed to the PayUMoney Technical team and got my answer why i am getting error "Sorry, Some Problem Occurred."
Got a quick reply for the Technical Team:
Recently, we have done some modifications in test environment due to which test key-JBZaLc and salt-GQs7yium will not work anymore.
In order to test the gateway using a test key and salt, kindly follow these steps:
1 - Go on https://test.payumoney.com
2 - Sign up as a merchant - use any of your valid email ids - kindly do not use a random email id.
3 - Complete the "Business Details" - you may use PAN no. ABCDE1234F and DOB - 01/04/1990
4 - Complete "Bank Account Details" (You may use IFSC- ALLA0212632)
5 - Go to below mentioned location to get the Test Merchant Id :
Seller Dashboard -> Settings -> My account -> Profile Settings
Once you provide your test merchant id, we will approve it so that you can find your test key and salt at :
Seller Dashboard -> Settings -> My account -> Merchant Key - Salt
Download Github Repository
For swift Version
1) import into bridging header
** import CommonCrypto/CommonDigest.h **
2) after
func sha512Hex( string: String) -> String {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
if let data = string.data(using: String.Encoding.utf8) {
let value = data as NSData
CC_SHA512(value.bytes, CC_LONG(data.count), &digest)
}
var digestHex = ""
for index in 0..<Int(CC_SHA512_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}
return digestHex
}
3) install pod PlugNPlay
4) after follow step provided PlugNPlay
I am developing an iOS application. I have to send an audio file to our server programmatically. I am using the following code to send an sample wav audio file to server. Our server accepts only audio file in signed bytes array format for receiving.
NSURL *urlPath = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"Crash" ofType:#"wav"]];
NSString *wavbundlepath = [urlPath absoluteString];
NSLog(#"wavbundlepath: %#",wavbundlepath);
NSData *bytes = [wavbundlepath dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"bytes: %#",bytes);
NSString *recordPostLength = [NSString stringWithFormat:#"%d", [bytes length]];
NSMutableString *urlstr = [NSMutableString stringWithFormat:#"%#", #"http://www.mywebserver/api/UploadFile?Name="];
[urlstr appendString:#"crash"];
[urlstr appendFormat:#"&MemberID=%d", 0];
[urlstr appendFormat:#"&Type=%#",#"Recording"];
[urlstr appendFormat:#"&client=%#",#"ios"];
NSLog(#"urlstr.......%#",urlstr);
NSMutableURLRequest *recordRequest = [[NSMutableURLRequest alloc] init] ;
[recordRequest setURL:[NSURL URLWithString:urlstr]];
[recordRequest setHTTPMethod:#"POST"];
[recordRequest setValue:recordPostLength forHTTPHeaderField:#"Content-Length"];
[recordRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[recordRequest setHTTPBody:bytes];
NSURLResponse *recordResponse;
NSError *recordError;
NSData *recordResponseData = [NSURLConnection sendSynchronousRequest:recordRequest returningResponse:&recordResponse error:&recordError];
NSString *recordResp = [[NSString alloc]initWithData:recordResponseData encoding:NSUTF8StringEncoding];
NSLog(#"recordResp:%#", recordResp);
But the problem is, always receving "Input string is not correct." response error.
I am not very much aware of uploading audio bytes to server. Could someone please check this code and tell me this is valid code or not for uploading a wav audio bytes array to server?
Thank you.
UPDATED CODE
I tried below code as my server side engineer said not to have any other things post body, and it works fine and getting positive response. But, the server is not able to work with format NSData bytes (32 bit elements) what i'm sending, because server side its implemented to receive only array of bytes or signed bytes data format only.
NSURL *urlPath = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"Temp" ofType:#"wav"]];
NSString *wavbundlepath = [urlPath absoluteString];
NSLog(#"wavbundlepath: %#",wavbundlepath);
NSData *bytes=[NSData dataWithContentsOfURL:urlPath];
NSLog(#"bytes: %#",bytes);
NSString *recordPostLength = [NSString stringWithFormat:#"%d", [bytes length]];
NSMutableString *urlstr = [NSMutableString stringWithFormat:#"%#", #"http://www.myserver.com/api/UploadFile?Name="];
[urlstr appendString:#"Temp"];
[urlstr appendFormat:#"&MemberID=%d", 0];
[urlstr appendFormat:#"&Type=%#",#"Recording"];
[urlstr appendFormat:#"&client=%#",#"ios"];
NSLog(#"urlstr.......%#",urlstr);
NSMutableURLRequest *recordRequest = [[NSMutableURLRequest alloc] init] ;
[recordRequest setURL:[NSURL URLWithString:urlstr]];
NSInputStream *dataStream = [NSInputStream inputStreamWithData:bytes];
[recordRequest setHTTPBodyStream:dataStream];
[recordRequest setHTTPMethod:#"POST"];
NSURLResponse *recordResponse;
NSError *recordError;
NSData *recordResponseData = [NSURLConnection sendSynchronousRequest:recordRequest returningResponse:&recordResponse error:&recordError];
NSString *recordResp = [[NSString alloc]initWithData:recordResponseData encoding:NSUTF8StringEncoding];
NSLog(#"recordResp:%#", recordResp);
recordResponceJson = [recordResp JSONValue];
NSLog(#"recordResponceJson = %#",recordResponceJson);
recId = [recordResponceJson valueForKey:#"ID"];
NSLog(#"recId....%#", recId);
Could someone please guide me, how i can send array of bytes in this http post?
There are a couple problems:
First how you're reading the file will not return a valid WAV file:
You should use [NSData dataWithContentsOfURL:] to read the bytes. The way you're reading them it will try to convert the bytes into characters. This will corrupt your wav file.
Second, the content-type of the POST body is probably incorrect. See the line:
[recordRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
The audio bytes would not be encoded in x-www-form-urlencoded format. It is more likely that the server would accept a audio/wav or application/octet-stream content type. Check with your server developers to see exactly what the server is expecting.
Also, you may want to check out the NSMutableURLRequest method called setHTTPBodyStream: that lets you send a file without having to load the entire thing into memory.