PayUMoney payment gateway issue - ios

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

Related

how to create picker view did select row can be passed as parameter for post method

I am new to IOS i need to create parameter for POST method using picker view did select row.
Picker view did select row:
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if(pickerView.tag ==2){
txtText.text = (NSString *)[arrMsg objectAtIndex:row];
NSLog([arrmsg1 objectAtIndex:row]);
}else if(pickerView.tag ==1){
currency1.text = (NSString *)[currencyname1 objectAtIndex:row];
NSLog([id1 objectAtIndex:row]);
}
else
{
currency2.text = (NSString *)[from_currency objectAtIndex:row];
NSLog([id2 objectAtIndex:row]);
}
}
post method:
here str is considered as parameter for post method but i struggling how to call picker view did select row array as my parameter str.
-(void) sendDataToServer : (NSString *) method params:(NSString *)str{
NSData *postData = [str dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[str length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL]];
NSLog(#"%#",str);
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:request delegate:self];
if( theConnection ){
mutableData = [[NSMutableData alloc]init];
}
}
viewdidload:
coding :
- (void)viewDidLoad {
[super viewDidLoad];
NSString *parseURL =#"Url1";
NSString *encodeurl =[parseURL stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:encodeurl];
NSData *data = [NSData dataWithContentsOfURL:url];
if(data){
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options: kNilOptions error:&error];
arrMsg = [json valueForKeyPath:#"Branches.branch_name"];
//NSLog(#"%#",json);
arrmsg1 =[json valueForKeyPath:#"Branches.id"];
firststr = [arrmsg1 componentsJoinedByString:#","];
NSLog(#"%#",arrmsg1);
arrMsg.count!=0;
if (arrMsg.count >0)
{
txtText.text = (NSString *)[arrMsg objectAtIndex:0];
}
}
//second textfield and third textfield
NSString *parseURL1 =#"url2";
NSString *encodeurl1 =[parseURL1 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url1 = [NSURL URLWithString:encodeurl1];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
if(data1){
NSError *error1;
NSDictionary *json1 = [NSJSONSerialization JSONObjectWithData:data1 options: kNilOptions error:&error1];
//NSLog(#"%#",json1);
currencyname1 = [json1 valueForKeyPath:#"Currencies.currency_name"];
id1 = [json1 valueForKeyPath:#"Currencies.id"];
NSLog(#"%#",id1);
from_currency = [json1 valueForKeyPath:#"Currencies.currency_name"];
id2 = [json1 valueForKeyPath:#"Currencies.id"];
secondstr = [id1 componentsJoinedByString:#","];
thirdstr = [id2 componentsJoinedByString:#","];
NSLog(#"%#",secondstr);
NSLog(#"%#",thirdstr);
//NSLog(#"%#",json1);
currencyname1.count!=0;
if (currencyname1.count >0)
{
currency1.text = (NSString *)[currencyname1 objectAtIndex:0];
}
from_currency.count!=0;
if (from_currency.count >0)
{
currency2.text = (NSString *)[from_currency objectAtIndex:0];
}
}
str = [NSString stringWithFormat:#"branch_id=%#&from_curr=%#&to_curr=%#&value=%#",firststr,secondstr,thirdstr,fourthstr];
pktStatePicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
pktStatePicker .delegate = self;
pktStatePicker .dataSource = self;
txtText.delegate = self ;
currency1.delegate = self;
currency2.delegate = self;
[ pktStatePicker setShowsSelectionIndicator:YES];
You should set tag to your text fields.
Then on button click you can get text of your textfields and call sendDataToServer method from this button click not from did select row.
Hope this will help :)

How to print the json data

I'm trying to learn JSON with IOS since I'm a beginner in IOS devices, i tried this code so far
-(void)retriveData
{
NSURL *url = [NSURL URLWithString:#"http://localhost/testjson.php"];
NSData *data = [NSData dataWithContentsOfURL:url];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
cities = [[NSMutableArray alloc] init];
for (int i=0; i<json.count; i++) {
NSString *cID = [[json objectAtIndex:i] objectForKey:#"id"];
NSString *cName = [[json objectAtIndex:i] objectForKey:#"CityName"];
NSString *cState = [[json objectAtIndex:i] objectForKey:#"CityState"];
NSString *cPopulation = [[json objectAtIndex:i] objectForKey:#"CityPopulation"];
NSString *cCountry = [[json objectAtIndex:i] objectForKey:#"Country"];
Country *myCity = [[Country alloc] initWithCityID:cID andCityName:cName andCityState:cState andCityPopulation:cPopulation andCityCountry:cCountry];
[cities addObject:myCity];
}
}
Anyone can show me now how i can print the data? this is the json file
[{"0":"1","id":"1","1":"Muscat","CityName":"Muscat","2":"Muscat","CityState":"Muscat","3":"25000","CityPopulation":"25000","4":"Oman","Country":"Oman"},{"0":"2","id":"2","1":"Bawsher","CityName":"Bawsher","2":"Muscat","CityState":"Muscat","3":"10000","CityPopulation":"10000","4":"Oman","Country":"Oman"},{"0":"3","id":"3","1":"AlMawalih","CityName":"AlMawalih","2":"Seeb","CityState":"Seeb","3":"5000","CityPopulation":"5000","4":"Oman","Country":"Oman"},{"0":"4","id":"4","1":"Oran","CityName":"Oran","2":"Oran","CityState":"Oran","3":"100000","CityPopulation":"100000","4":"Algeria","Country":"Algeria"},{"0":"5","id":"5","1":"Constantine","CityName":"Constantine","2":"Constantine","CityState":"Constantine","3":"150000","CityPopulation":"150000","4":"Algeria","Country":"Algeria"}]
Below is my very understandable and basic coding according to your question.It is helpful for you.
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://localhost/testjson.php"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
//You need to check response.Once you get the response copy that and paste in ONLINE JSON VIEWER in GOOGLE.If you do this clearly you can get the correct results.
//After that it depends upon the json format whether it is DICTIONARY or ARRAY
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error: &err];
NSLog(#"The json output array is - %#",jsonArray);
for(int i=0;i>[jsonArray count];i++)
{
NSString *strZero = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"0"]];
NSLog(#"The zero is-%#",strZero);
NSString *strOne = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"1"]];
NSLog(#"The One is-%#",strOne);
NSString *strTwo = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"2"]];
NSLog(#"The Two is-%#",strTwo);
NSString *strThree = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"3"]];
NSLog(#"The three is-%#",strThree);
NSString *strFour = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"4"]];
NSLog(#"The four is-%#",strFour);
NSString *strID = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"id"]];
NSLog(#"The ID is-%#",strID);
NSString *strCityName = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"CityName"]];
NSLog(#"The CityName is-%#",strCityName);
NSString *strCityState = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"CityState"]];
NSLog(#"The CityState is-%#",strCityState);
NSString *strCityPopulation = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"CityPopulation"]];
NSLog(#"The CityPopulation is-%#",strCityPopulation);
NSString *strCountry = [NSString stringWithFormat:#"%#",[array objectAtIndex:i]valueForKey:#"Country"]];
NSLog(#"The Country is-%#",strCountry);
}
By printing you mean show the data in the console ?
Did you try this ?
NSString* str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Data: %#", str);

Is there any Two-Legged OAuth library support RSA-SHA1 signing for iOS?

I was trying to implement MasterCard MoneySend API in iOS. The API require two-legged oauth to authorize the request.
The criteria are:
OAuth should use RSA-SHA1 for generating signature.
request method should be PUT
since the request has a body, need to include body hash.
What we have is a ConsumerKey and .p12 file of PrivetKey. I tryed many libraries like RestKit, ASIHTTPRequest, OAuthConsumer, etc.
Finally I ended up with this piece of code:
#import "NSStringAdditions.h"
#import "ASIHTTPRequest.h"
#import "sha.h"
#import "rsa.h"
#import "pem.h"
#import "objects.h"
#define SANDBOX_CONSUMER_KEY #""
#define PRIVETKEY #""
#interface MC_TestApi ()
<NSURLConnectionDelegate>
{
NSMutableData *responseData;
NSURLConnection *urlConnection;
}
#end
#implementation MC_TestApi
- (NSString*)oAuthBodyHash:(NSData*)body
{
unsigned char digest[SHA_DIGEST_LENGTH];
SHA1([body bytes], [body length], (unsigned char*)&digest);
unsigned c = SHA_DIGEST_LENGTH;
uint8_t *bytes = malloc(sizeof(*bytes) * c);
unsigned i;
for (i = 0; i < c; i++)
{
int byte = (unsigned int)digest[i];
bytes[i] = (uint8_t)byte;
}
NSData *strData = [NSData dataWithBytesNoCopy:bytes length:c freeWhenDone:YES];
return [NSString base64StringFromData:strData length:strData.length ];
}
- (NSString *)sha1RsaText: (NSString *)text
{
NSString *path = [[NSBundle mainBundle] pathForResource: #"MCOpenAPI" ofType: #"pem"];
FILE *secretFile = fopen([path cStringUsingEncoding: NSUTF8StringEncoding], "r");
if (secretFile==NULL){
printf("ERROR opening RSA Keys failed test.pem\n");
return nil;
}
NSData *clearTextData = [text dataUsingEncoding: NSUTF8StringEncoding];
unsigned char encryptedData[40];
RSA *rsa = (RSA *)PEM_read_RSAPrivateKey(secretFile, &rsa, NULL, NULL);
unsigned int encryptionLength = 40; //RSA_size(rsa);
RSA_sign(NID_sha1, [clearTextData bytes], [clearTextData length], encryptedData, &encryptionLength, rsa);
unsigned c = 20;
uint8_t *bytes = malloc(sizeof(*bytes) * c);
unsigned i;
for (i = 0; i < c; i++)
{
int byte = (unsigned int)encryptedData[i];
bytes[i] = (uint8_t)byte;
}
NSData *strData = [NSData dataWithBytesNoCopy:bytes length:c freeWhenDone:YES];
return [NSString base64StringFromData:strData length:strData.length ];
}
- (NSString *)urlEncodeValue:(NSString *)str
{
NSString *result = (NSString *) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)str,
NULL,
CFSTR(":/?#[]#!$&'()*+,;="),
kCFStringEncodingUTF8));
return result;
}
-(void)requestWithOAuth {
NSUInteger time = [[NSDate date] timeIntervalSince1970];
NSString *timestamp = [NSString stringWithFormat: #"%d", time];
NSString *urlString = #"https://sandbox.api.mastercard.com/moneysend/eligibility/v1/pan";
NSString *nonce = #"1234567890";
NSString *consumerKey = SANDBOX_CONSUMER_KEY;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#?Format=XML",urlString]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"PUT"];
[request setValue:#"application/xml" forHTTPHeaderField:#"content-type"];
NSString *bodyString = #"<?xml version=\"1.0\" encoding=\"UTF-8\" ?> <PanEligibilityRequest> <SendingAccountNumber>5555555555559999</SendingAccountNumber> </PanEligibilityRequest>";
NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
NSString *bodyLength = [NSString stringWithFormat:#"%d",[body length]];
[request setValue:bodyLength forHTTPHeaderField:#"content-length"];
NSString *oAuthBodyHash = [self oAuthBodyHash:body];
NSString *header = [NSString stringWithFormat:#"oauth_timestamp=\"%#\",oauth_nonce=\"%#\",oauth_version=\"1.0\",oauth_body_hash=\"%#\",oauth_consumer_key=\"%#\",oauth_signature_method=\"RSA-SHA1\"",timestamp,nonce,oAuthBodyHash,SANDBOX_CONSUMER_KEY];
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:
consumerKey,#"oauth_consumer_key",
nonce,#"oauth_nonce",
#"RSA-SHA1",#"oauth_signature_method",
timestamp,#"oauth_timestamp",
#"1.0",#"oauth_version",
oAuthBodyHash,#"oauth_body_hash",
#"XML",#"Format",
nil];
NSArray *keys = [parameters allKeys];
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES selector:#selector(localizedCompare:)];
keys = [keys sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSString *test = #"";
for (NSUInteger i = 0; i<[keys count]; i++) {
NSString *key = [keys objectAtIndex:i];
NSString *str = [NSString stringWithFormat:#"%#=%#",key,[parameters objectForKey:key]];
if (i!=([parameters count]-1))
str = [str stringByAppendingString:#","];
test = [test stringByAppendingString:str];
}
NSString *signatureString = [NSString stringWithFormat: #"PUT&%#%%26%#",
[self urlEncodeValue: urlString],
[self urlEncodeValue: [test stringByReplacingOccurrencesOfString: #"," withString: #"&"]]];
NSString *signature = [self sha1RsaText: signatureString];
NSString *finalAuthHeader = [NSString stringWithFormat: #"OAuth %#,oauth_signature=\"%#\"", header, signature];
[request setValue:finalAuthHeader forHTTPHeaderField:#"Authorization"];
[request setHTTPBody:body];
urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[urlConnection start];
}
#pragma mark - NSURLConnectionDelegate
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int code = [httpResponse statusCode];
NSLog(#"in didReceiveResponse %i %#",code,[NSHTTPURLResponse localizedStringForStatusCode:code]);
responseData = nil;
responseData = [[NSMutableData alloc] init];
[responseData setLength:0];
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"in didReceiveData ");
[responseData appendData:data];
}
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSLog(#"\n\n ERORR \n\n%#",[NSString stringWithFormat:#"Connection failed: %#", [error description]]);
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
if (responseData) {
NSString *newStr = [NSString stringWithUTF8String:[responseData bytes]];
NSLog(#"XML: %#",newStr);
}
responseData = nil;
}
#end
My question is:
What I am doing wrong here?
Is there any Open source library in iOS that i can use?
Guys Please help me on this... thanks and regards
Try to use chilkatsoft
or just native CommonCrypto (an Apple framework)

Images downloading intermittently

I have an iPad app which connects to a C# web service to download documents and images.
If I run it as a fresh install on the iPad, it downloads the expected documents and images. If I upload a new document and relaunch the app, it downloads it as expected. However, if I upload a new image to the server and run it again, it doesn't download the new image.
Here is the code for checking and downloading documents:
- (void)checkFiles:(NSString *)sessionID
{
fileList = [[NSMutableString alloc] init];
// get contents of doc directory
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [directoryPaths objectAtIndex:0];
NSString *downloadsFolderString = [documentsDirectory stringByAppendingPathComponent:DOWNLOADS_FOLDER];
NSError *error = nil;
NSString* file;
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:downloadsFolderString];
while (file = [enumerator nextObject])
{
BOOL isDirectory = NO;
[[NSFileManager defaultManager] fileExistsAtPath: [NSString stringWithFormat:#"%#/%#", downloadsFolderString,file]
isDirectory: &isDirectory];
if ([file rangeOfString:#"LinkIcons"].location == NSNotFound)
{
if (!isDirectory)
{
[fileList appendString:[NSString stringWithFormat:#"%#|", file]];
}
}
}
// create string to send to server
NSString *post = [NSString stringWithFormat:#"sessionID=%#&fileList=%#&dateTime=%#&userID=%#", sessionID, fileList, timeOpened, userID];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSString *comparisonURLString = SERVER_COMPARE_URL_STRING;
NSURL *comparisonURL = [NSURL URLWithString:comparisonURLString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:comparisonURL];
[request setHTTPMethod:#"POST"];
[request addValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
// get response - list of files for download
NSHTTPURLResponse *urlResponse = nil;
error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
if (responseData)
{
NSString *requiredFilesList = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
// remove xml nodes from list
NSArray *lines = [requiredFilesList componentsSeparatedByString: #"\n"];
if (lines.count > 2)
{
// create sub array without xml nodes
NSRange theRange;
theRange.location = 2;
theRange.length = [lines count] -3;
numberOfFilesToBeDownloaded = theRange.length;
if (numberOfFilesToBeDownloaded <= 0)
{
_jobStatusLabel.text = #"Documents up to date";
}
if (numberOfFilesToBeDownloaded > 0)
{
NSArray *subArray = [lines subarrayWithRange:theRange];
[self getFiles:subArray];
}
}
}
[self checkLinks];
}
and:
- (void)getFiles:(NSArray *)filenames
{
downloadManager = [[DownloadManager alloc] init];
downloadManager.delegate = self;
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *downloadFolder = [documentsPath stringByAppendingPathComponent:#"downloads"];
for (NSString *filename in filenames)
{
NSString *downloadFilename = [downloadFolder stringByAppendingPathComponent:filename];
NSString *baseUrlString = SERVER_DOWNLOAD_URL_STRING;
NSString *finalUrlString = [baseUrlString stringByAppendingPathComponent:[filename stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[downloadManager addDownload:downloadFilename fromUrl:[NSURL URLWithString:finalUrlString] ];
[self notifyServerFileDownloaded:filename];
}
}
And this is the corresponding code for the images:
- (void) checkLinks
{
NSMutableString *linkListOnDevice = [[NSMutableString alloc] init];
NSMutableArray *globalLinksArray = [[[NSUserDefaults standardUserDefaults] objectForKey:#"globalLinksArray"]mutableCopy];
if(globalLinksArray != nil)
{
NSLog(#"Links Array found. Contents: %#", globalLinksArray);
}
else
{
globalLinksArray = [[NSMutableArray alloc] initWithCapacity:0];
}
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [directoryPaths objectAtIndex:0];
NSString *downloadsFolderString = [documentsDirectory stringByAppendingPathComponent:DOWNLOADS_FOLDER];
NSString *LinksFolderString = [downloadsFolderString stringByAppendingPathComponent:#"/LinkIcons"];
NSError *error = nil;
NSString* file;
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:LinksFolderString];
while (file = [enumerator nextObject])
{
BOOL isDirectory = NO;
[[NSFileManager defaultManager] fileExistsAtPath: [NSString stringWithFormat:#"%#/%#",downloadsFolderString,file]
isDirectory: &isDirectory];
if (!isDirectory)
{
[linkListOnDevice appendString:[NSString stringWithFormat:#"%#|", file]];
}
}
// create string to send to server
NSString *post = [NSString stringWithFormat:#"iconsList=%#&userID=%#", linkListOnDevice, userID];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSString *comparisonURLString = SERVER_COMPARE_LINK_ICONS_URL_STRING;
NSURL *comparisonURL = [NSURL URLWithString:comparisonURLString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:comparisonURL];
[request setHTTPMethod:#"POST"];
[request addValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
// get response - list of files for download
NSHTTPURLResponse *urlResponse = nil;
error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
NSString *requiredIconsList = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
// remove xml nodes from list
NSArray *lines = [requiredIconsList componentsSeparatedByString: #"\n"];
// create sub array without xml nodes
NSRange theRange;
theRange.location = 2;
theRange.length = [lines count] -3;
numberOfFilesToBeDownloaded += theRange.length;
NSArray *linkSubArray = [lines subarrayWithRange:theRange];
NSMutableArray *iconsArray = [[NSMutableArray alloc] initWithCapacity:0];
NSString *linkDetail;
for (linkDetail in linkSubArray) {
[globalLinksArray addObject:linkDetail];
}
[[NSUserDefaults standardUserDefaults] setObject:globalLinksArray forKey:#"globalLinksArray"];
[[NSUserDefaults standardUserDefaults] synchronize];
// separate file for download from rest of string
for (NSString *linkString in linkSubArray)
{
NSArray *spltArray = [linkString componentsSeparatedByString:#"^"];
NSString *linkIconString = spltArray[3];
[iconsArray addObject:linkIconString];
}
[self getLinks:iconsArray];
}
and:
- (void) getLinks: (NSMutableArray *) linkList
{
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *downloadFolder = [documentsPath stringByAppendingPathComponent:#"downloads"];
for (NSString *filename in linkList)
{
NSString *downloadFilename = [downloadFolder stringByAppendingPathComponent:filename];
NSString *baseUrlString = SERVER_DOWNLOAD_URL_STRING;
NSString *finalUrlString = [baseUrlString stringByAppendingPathComponent:[filename stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[downloadManager addDownload:downloadFilename fromUrl:[NSURL URLWithString:finalUrlString] ];
}
}
Can anyone shed any light on why this works for documents but for images only on first run but not subsequently?
1) write this on didFinishLaunchingWithOptions method
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"FirstTime"];
if (![savedValue isEqualToString:#"1"])
{
//Call for download image OR image downloading coding.
}
2) When image downloading complete then store value in NSUserDefaults
NSString *valueToSave = #"1";
[[NSUserDefaults standardUserDefaults]
setObject:valueToSave forKey:#"FirstTime"];
3) when next time your app is run then (1) condition is true and it not download image next time. If you want to download this then delete your app from simulator or device and clean then run the app.

Received memory warning and app crash while uploading more than 100 images on my server

I am uploading more than 100 images on server using following code and i Received memory warning after uploading few images. Please help me..
Here is my code for uploading image on sever :
-(void)uploadSingleFile
{
if(!self.objWebServices.bSyncWasOn)
{
NSLog(#"STOP upload Single File RETURN");
[self Call_SaveSyncedImageID];
return;
}
SyncItem* item = [arrSelSyncItemIDS objectAtIndex:nSyncItemIndex];
if(item.nType == SYNC_STATUS_NOT_SELECTED || item.nType == SYNC_STATUS_SYNC_DONE)
{
nSyncItemIndex = nSyncItemIndex + 1;
if([arrSelSyncItemIDS count] > nSyncItemIndex)
{
NSLog(#"Called uploadSingleFile");
[self uploadSingleFile];
return;
}
else
{
//[self LoadImages:!bShowHideSyncImages];
[SVProgressHUD dismiss];
[BtnStopSync setTitle:#"Start sync" forState:UIControlStateNormal];
self.objWebServices.bSyncWasOn = NO;
self.objWebServices.isFileUpload = NO;
if( [[NSUserDefaults standardUserDefaults] boolForKey:#"Notification_State"] ) // Setting Switch Bool
{
UIAlertView *Alert = [[UIAlertView alloc] initWithTitle:#"test" message:#"*** Sync completed successfully." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Alert show];
}
}
}
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *srtprefSessionId = [NSString stringWithFormat:#"%#",[prefs objectForKey:#"prefSessionId"]];
BOOL isTrash = FALSE;
NSString *StrPath = #"/Pictures/"; //Change
ALAsset* temp = item.itemAsset;
NSDate* assetDate = (NSDate*)[temp valueForProperty:#"ALAssetPropertyDate"];
NSString* strID = #"";
strID = [[temp valueForProperty:#"ALAssetPropertyURLs"] description];
strID = [strID stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString* strImageType = #"";
if ([strID rangeOfString:#"jpg"].location != NSNotFound || [strID rangeOfString:#"JPG"].location != NSNotFound ){
strImageType = #"jpg";
}
else if ([strID rangeOfString:#"png"].location != NSNotFound || [strID rangeOfString:#"PNG"].location != NSNotFound )
strImageType = #"png";
NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"MM/dd/yyyy"];
NSString *result = [df stringFromDate:assetDate];
NSTimeInterval timeInterval = [assetDate timeIntervalSince1970];
ALAssetRepresentation *rep = [temp defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
StrPath = [StrPath stringByAppendingFormat:#"%d.%#",(int)timeInterval,strImageType];
//UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
UIImage *image =[UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];
//------------------ metadata -------------------------------------------------------
NSDictionary *imageMetadata = [rep metadata];
NSString *strOrt=[NSString stringWithFormat:#"%#",[imageMetadata valueForKey:#"Orientation"]];
NSData *dataObj = nil;
dataObj = UIImageJPEGRepresentation(image, 1.0);
NSString* StrFileData = [Base64 encode:dataObj];
NSString* strFileHash = [dataObj md5Test];
NSMutableDictionary *DictRequest = [[NSMutableDictionary alloc]init];
[DictRequest setObject:srtprefSessionId forKey:#"SessionId"];
[DictRequest setObject:StrPath forKey:#"Path"];
[DictRequest setValue:[NSNumber numberWithBool:isTrash] forKey:#"UploadDirectlyToTrashbin"];
[DictRequest setObject:StrFileData forKey:#"FileData"];
[DictRequest setObject:strFileHash forKey:#"FileHash"];
[DictRequest setObject:result forKey:#"DateCreated"];
BOOL isNULL = [self stringIsEmpty:strOrt];
if(!isNULL)
{
//[DictRequest setObject:strOrt forKey:#"Orientation"];
}
NSString *jsonString = [DictRequest JSONRepresentation];
NSString *strUrl=[NSString stringWithFormat:#"%#",FileUpload_URL];
NSURL *url1=[NSURL URLWithString:strUrl];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url1];
[request setTimeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
[request setHTTPBody:postData];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
if(theConnection)
[self Set2Defaults];
theConnection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[SVProgressHUD dismiss];
if(theConnection)
webData = [NSMutableData data];
else
NSLog(#"Connection Failed !!!");
}
Try this:
-(void)uploadSingleFile
{
#autoreleasepool
{
...
...
}
}
Why need of these many operations ????
NSData *dataObj = nil;
dataObj = UIImageJPEGRepresentation(image, 1.0);
NSString* StrFileData = [Base64 encode:dataObj];
NSString* strFileHash = [dataObj md5Test];
Also I suggest you to compress image before sending, since NSData will be huge. This can be managed from server side
Try compressing image before sending :
CGFloat compression = 0.9f;
NSData *imageData = UIImageJPEGRepresentation([item image], compression);
while ([imageData length] > 700000 && compression > 0.1) {
// NSLog(#"Image size too big, compression more: current data size: %d bytes",[imageData length]);
compression -= 0.1;
imageData = UIImageJPEGRepresentation([item image], compression);
}
Set up the cachePolicy to avoid cache
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData

Resources