In App Purchase Autorenew Receipt Format Problems - in-app-purchase

I have an auto-renewable in-app purchase. When the user signs up for the first time, the app receives a receipt in the form of NSDATA. I encode that into a string:
[NSString stringWithUTF8String:[receiptData bytes]]];
Then I post it to my server as a blob.
Then when the user signs into the app, I get the receipt from my server, change it into NSDATA:
[receipt dataUsingEncoding:NSUTF8StringEncoding]
then I run a method on it to verify that the receipt is valid. From my reading I have gathered that responses will be a newer receipt, or a status code of some sort saying its valid or not.
NSString *jsonObjectString = [self encodeBase64:(uint8_t *)receipt.bytes
length:receipt.length];
NSString *itunescombo = #"xxxxxxxxxxxxxxxxxxxxxx";
// Create the POST request payload.
NSString *payload = [NSString stringWithFormat:#"{\"receipt-data\" : \"%#\", \"password\" : \"%#\"}",
jsonObjectString, itunescombo];
NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
NSString *serverURL = ITMS_SANDBOX_VERIFY_RECEIPT_URL;
// Create the POST request to the server.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:serverURL]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:payloadData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn start];
Then as a response, I keep getting either:
{"status":21002, "exception":"java.lang.IllegalArgumentException"}
or just
{"status":21002}
Can someone please tell me where I am going wrong? That error means that the format of the receipt is incorrect but I am not sure where this is happening between all the format manipulating.
Thank you!
R

Once change your code to
NSString *jsonObjectString = [self encodeBase64:(uint8_t *)transaction.transactionReceipt.bytes
length:transaction.transactionReceipt.length];

Related

Posting JSON to API with URL on IOS

I have designing an alarm and according to that alarm I need to post on api what the user set as alarm, later api will handle the procedure and notif me if the alarm time is come. So basically, I searched all day long and come with those:
Here what I came so far with tons of efforts! Please help me for further..
NSMutableDictionary *alarmDic = [[NSMutableDictionary alloc] initWithCapacity:4];
NSLog(#"token: %#", self.token);
[alarmDic setObject:[NSNumber numberWithInteger:42] forKey:#"Token"];
NSLog(#"kur id: %lu", alarm.kurID);
[alarmDic setObject:[NSNumber numberWithInteger:alarm.kurID] forKey:#"CurrencyId"];
NSLog(#"not val: %f", alarm.kurAlis);
[alarmDic setObject:[NSNumber numberWithFloat:alarm.kurAlis] forKey:#"NotificationValue"];
NSLog(#"%ld", (long)alarm.kurTur);
[alarmDic setObject:[NSNumber numberWithInteger:alarm.kurTur] forKey:#"Type"];
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:alarmDic
options:NSJSONWritingPrettyPrinted
error:nil];
NSLog(#"%#", [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding]);
NSString *dataLength = [NSString stringWithFormat:#"%lu", (unsigned long)[jsonData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://api-dvzalt.azurewebsites.net/api/Notification/PostNotification"]];
[request setHTTPMethod:#"POST"];
[request setValue:dataLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:jsonData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(conn) {
NSLog(#"Connection Successful");
} else {
NSLog(#"Connection could not be made");
}
In the log windows,
requestReply: Connection Successful
However, nothing happening on the api, telling this as always.
The requested resource does not support http method 'GET'.
Here is the confusion I have. It says connection succesful but on API, still the same. What should I do in this case? I might skip something but I can't figure out what I skip. I've done with the whole steps I suppose.
Note: API is working great, it is about my code most probably.
Thanks !
So I'm curious if you don't have a field name for the JSON data in your web handler? Something like "jsonData"? Right now you're stuffing the JSON data in your body, but there's no identifying field name for the handler to pull it out.
I'm thinking something like:
NSString jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString requestString = [NSString stringWithFormat:#"jsonData=%#", jsonString];
Then encode requestString and use it in your body.

Send MMS using Twilio in ios

I want to send MMS using Twilio.
I am request one twilio url which is work fine on SMS but not MMS and I want to know what should change so i am sending MMS using Twilio in iOS.
Here is my code.
NSLog(#"Sending request.");
// Common constants
NSString *kTwilioSID =#"Twilio SID";
NSString *kTwilioSecret =#"Twilio Secret";
NSString *kFromNumber = #"From Phone Number";
NSString *kToNumber = #"To Phone number";
NSString *kMessage=#"Hello This is Pintu vasani";
// Build request
NSString *urlString = [NSString stringWithFormat:#"https://%#:%##api.twilio.com/2010-04-01/Accounts/%#/SMS/Messages", kTwilioSID, kTwilioSecret, kTwilioSID];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
// Set up the body MediaUrl
NSString *bodyString = [NSString stringWithFormat:#"From=%#&To=%#&Body=%#", kFromNumber, kToNumber, kMessage];
NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
NSError *error;
NSURLResponse *response;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
// Handle the received data
if (error) {
NSLog(#"Error: %#", error);
} else {
NSString *receivedString = [[NSString alloc]initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(#"Request sent. %#", receivedString);
}
Twilio developer evangelist here.
You seem to be using the old, deprecated Sms resource which doesn't support MMS. You really want to be using the Messages resource which does work.
On a separate note, I would not recommend making API calls directly to Twilio from your iOS application (or any other client application). To do this you would need to embed your Twilio credentials within the application which is dangerous. I would recommend sending the SMS/MMS from a server side application as in this example.

XMLRPC from iOS App New Post

I am trying to add ability to my app to post a new article to a wordpress blog. I know that Wordpress has the XMLRPC, but I am having issues in implementing the wp.newPost as there is little documentation outside of Ruby PHP or JAVA.
Here is what I have in my app:
-(IBAction)postNews {
NSURL *xmlrpcURL = [NSURL URLWithString:#"https://myurl.wordpress.com/xmlrpc.php"];
NSString *username = #"email#yahoo.com";
NSString *password = #"password";
NSString *title = #"Test";
NSString *content = #"This is a test of posting to the news section from the app.";
NSString *myRequestString = [NSString stringWithFormat:#"username=%#&password=%#&content=%#", username, password, title];
// Create Data from request
NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: xmlrpcURL];
// set Request Type
[request setHTTPMethod: #"POST"];
// Set content-type
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
// Set Request Body
[request setHTTPBody: myRequestData];
// Now send a request and get Response
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
// Log Response
NSString *response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSLog(#"%#",response);
}
I constantly get the response:
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>-32700</int></value>
</member>
<member>
<name>faultString</name>
<value><string>parse error. not well formed</string></value>
</member>
</struct>
</value>
</fault>
</methodResponse>
What am I doing wrong with this?
Ok, for those trying to do this, documentation for Obj-C is fairly difficult to find, but here is what I did. I first imported the XMLRPC Starter Kit from here. Next, in my app I defined the server username and password as it suggests, and in my action I used both an NSDictionary and NSArray for the post to go through. Again, this is for a simple text post to a wordpress blog.
NSString *server = kWordpressBaseURL;
XMLRPCRequest *reqFRC = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
NSDictionary* filter = #{
#"post_type": #"post",
#"post_status": #"publish",
#"post_title": #"Test Title",
#"post_content": #"Test Content",
};
NSArray *postParams = #[ #0, kWordpressUserName, kWordpressPassword, filter, #[#"post_title"]]; [reqFRC setMethod:#"wp.newPost" withObjects:postParams];
//The result for this method is a string so we know to send it into a NSString when making the call.
NSString *result = [self executeXMLRPCRequest:reqFRC];
[reqFRC release]; //Release the request
//Basic error checking
if( ![result isKindOfClass:[NSString class]] ) //error occured.
NSLog(#"demo.sayHello Response: %#", result);
Obviously, you can have text fields that you pull from for your blog post content, but this worked great!
U can add new posts using xmlrpc as given code
XMLRPCRequest *req = [[XMLRPCRequest alloc] initWithURL:[NSURL URLWithString:#"your url name"]];
NSArray *yourparameter = #[#0,#"your user id",#"your password"];
[request setMethod:#"wp.newPost" withParameters:yourparameter];
XMLRPCResponse *saveRessponse = [XMLRPCConnection sendSynchronousXMLRPCRequest:req error:nil];
NSLog(#"The Response is%#",[saveRessponse object]);
You can add new post using xml-rpc as
XMLRPCRequest *reqFRC = [[XMLRPCRequest alloc] initWithURL:[NSURL URLWithString:#"your url name"]];
// Set your url here.
NSArray *params = #[#0,#"your user id",#"your password"];
// Add your url parameters here.
[request setMethod:#"wp.newPost" withParameters:params]; // To add new post.
XMLRPCResponse *nodeSaveRessponse = [XMLRPCConnection sendSynchronousXMLRPCRequest:request error:nil];
NSLog(#"server response :%#",[nodeSaveRessponse object]);

Fetching an access token for youtube api iOS "Error" : "invalid_request"

I'm trying to get an access token for a youtube app for iOS. Here's the relevant code I have been using from my viewDidLoad method:
mAuth = [[GTMOAuth2Authentication alloc]init];
[mAuth setClientID:#"<MY CLIENT ID>"];
[mAuth setClientSecret:#"<MY CLIENT SECRET>"];
[mAuth setRedirectURI:#"urn:ietf:wg:oauth:2.0:oob"];
[mAuth setScope:#"https://gdata.youtube.com"];
[self.web loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/auth?client_id=%#&redirect_uri=%#&scope=%#&response_type=code&access_type=offline", mAuth.clientID, mAuth.redirectURI, mAuth.scope]]]];
After this is called, the user has to grant access to their account, then I retrieve the auth code from the resulting page in the following code:
NSString *string = [self.web stringByEvaluatingJavaScriptFromString:#"document.title"];
if([string rangeOfString:#"Success"].location != NSNotFound){
NSLog(#"This is the code page");
NSString *importantCode = [[string componentsSeparatedByString:#"="] objectAtIndex:1];
NSLog(#"%#", importantCode);
if([self.defaults objectForKey:#"super important code"] == nil){
[self.defaults setObject:importantCode forKey:#"super important code"];
[self.defaults synchronize];
NSString *post = [NSString stringWithFormat:#"code=%#&client_id=%#&client_secret=%#&redirect_uri=%#&grant_type=code", [self.defaults objectForKey:#"super important code"], mAuth.clientID, mAuth.clientSecret, mAuth.redirectURI];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/token"]]];
[request setHTTPMethod:#"POST"]; [request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[self.web loadRequest:request];
}
[timer invalidate];
}
After that, I should be given the access token in response to my POST request, but instead I get a page that simply says:
{
"error" : "invalid_request"
}
Does anyone (see where I went wrong)/(know how to retrieve the access token)?
I’d be interested in knowing what the HTTP status code is... I suspect ”invalid_request” means 400, which almost always means there’s some irritating stupid little error in the way you composed your authent URI. I don’t know enough iOS/ObcJ to tell if you’ve properly URLescaped any funny characters in any of the parameter values, but it’s worth checking. Or a typo in one of the values, or an extra newline creeping in or something?
It was as simple as this, I had set the grant_type parameter to 'code' when it should have been 'authorisation_code' if you are reading this and you are using the youtube api, don't make the same mistake. If you're reading this and you're sending a POST request in general, this error "invalid_request" means that either you skipped one of the parameters you should have added, or you added it incorrectly.

How do I create a post for Disqus from iOS?

I'm developing an application for a client. This app enables user to read and post comment. Our client website have already used Discus. Now that we can retrieve the comment and display it natively. But we find no way to create a post and send it to Disqus. Does anyone have some experiences with Disqus on iOS ?
Any idea will be much appreciated.
Edit : our client website has an authentication system already and thus we also integrate that system to our app. Every time user post a comment in the app, we'll use his/her authentication information. We don't want user to authenticate again.
Here is a great solution which helps easily integrate Disqus into iOS apps https://github.com/moqod/disqus-ios. Works like a charm out of the box.
Not only you can make posts, but also authorize thru social networks and respond to comments.
You have the API set up on your server, correct? Then post a request to your server, pass it whatever API keys and credentials you need, and have the server make a post to the Disqus API on behalf of the client. Basically, build your own iOS API for interfacing with the Disqus API through your server.
Even better though would be to directly interact with the Disqus server by making requests using NSURLRequest/Connection. For more information on Disqus requests look here. That would make your app faster and be less error prone, unless you are doing some critical activity on your server, other than just posting and displaying comments.
#RahuGupta: Sorry if it's too late for a response. I posted comment using SSO, I don't know about posting as guest. But it should be easier.
In my case I post a comment using third party authentication server which means we authenticate users by ourselves. The technique called SSO. You may want to read the documentation about SSO on Disqus.
In case you need code snippet in objective-c :
NSMutableDictionary *dico = [[NSMutableDictionary alloc] init];
[dico setValue:[NSString stringWithFormat:#"uniqueId_%#",comment.authorID] forKey:#"id"];
[dico setValue:comment.authorName forKey:#"username"];
[dico setValue:comment.authorEmail forKey:#"email"];
NSString *message = [dico JSONRepresentation];
NSString *message64Based = [DataPost base64String:message];
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
NSString *secret = DISQUS_API_SECRET;
NSString *api_key = DISQUS_API_PUBLIC;
//comment.threadID will makes the app crashed, because when comment is not fully loaded, it's nil
NSString *threadID = [NSString stringWithFormat:#"%#",comment.threadID];
NSString *commentMessage = [[comment.rawMessage stringByReplacingOccurrencesOfString:#"=" withString:#"%3D"] stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSString *host = #"http://example.com";
NSString *referrer = #"example.com";
NSString *hmac = [self hashedValue:secret andData:[NSString stringWithFormat:#"%# %.0lf",message64Based, timeStamp]];
NSString *remote_auth_s3 = [[[NSString stringWithFormat:#"%# %# %.0lf", message64Based, hmac, timeStamp] stringByReplacingOccurrencesOfString:#"=" withString:#"%3D"] stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSMutableURLRequest *uploadRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://disqus.com/api/3.0/posts/create.json"] cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 60.0f];
NSMutableData *postData = (NSMutableData *)[[NSString stringWithFormat:#"_format=json&thread=%#&message=%#&remote_auth=%#&api_key=%#&strict=1", threadID , commentMessage, remote_auth_s3 , api_key] dataUsingEncoding:NSUTF8StringEncoding];
[uploadRequest setHTTPMethod:#"POST"];
[uploadRequest setHTTPBody: postData];
[uploadRequest setValue:[NSString stringWithFormat:#"%d", [postData length]] forHTTPHeaderField:#"Content-Length"];
[uploadRequest setValue:referrer forHTTPHeaderField:#"referrer"];
[uploadRequest setValue:host forHTTPHeaderField:#"host"];
[uploadRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSHTTPURLResponse *response=nil;
NSError *error = nil;
[NSURLConnection sendSynchronousRequest:uploadRequest returningResponse:&response error:&error];

Resources