I have created a web service to make a communication between an iOS application and a Joomla web site, and I used the GET method to communicate between the mobile application and the web service and also between the web service and the controller (PHP file that does the work and return the data) , but I didn't find how to convert the implementation to POST method here is the actual system :
ws.php : it's the web service (simple example )
<?php
$id = $_GET['id'] ; // get the data from the URL
// here i make testes
// then I redirect to the controller of the Joomla component that receive
// the call of the request the URL is actually the attribute "action" of
// an existing HTML Form that implement the login system, I added a
// parameter called web service to help me to modify the controller
// to make the difference between a normal call and a web service call
header("Location: index.php?option=com_comprofiler&task=login&ws=1&id=1");
?>
Controller.php : the receiver of the web service call and the web call (from browser)
<?php
// code added by me, in the existent controller of the component
// it was waiting for a form submitting, so I got to convert my data to POST here
if (isset($_GET['ws'])) // it's a web service call
{
$_POST['id'] = $_GET['id'] ;
// do the task ...
if ($correctLogin) // just an example
echo "1"
else
echo '0';
}
?>
I didn't put the real implementation, and it's just a simple example of the system, but it's the same
Call from the mobile
NSURL *url = [[NSURL alloc]initWithString:#"http://localhost/ws.php?id=1"];
NSData *dataUrl= [NSData dataWithContentsOfURL:url];
NSString *str = [[NSString alloc]initWithData:dataUrl
encoding:NSUTF8StringEncoding];
if(![str isEqualToString:#"0"])
NSLog(#"connected");
else
NSLog(#"not connected");
so I don't want to use the GET method, I just want to receive my data from the mobile using POST and also send the data to the controller using POST also, what is the best solution ?
If you want your app to send data using POST method, then I'm this code. I hope it will help.
It takes the data to be sent in dictionary object.
Ecodes the data to be sent as POST
and then returns the response (if you want the results in string format you can use [[NSString alloc] initWithData:dresponse encoding: NSASCIIStringEncoding]; when returning data)
-(NSData*) getData:(NSDictionary *) postDataDic{
NSData *dresponse = [[NSData alloc] init];
NSURL *nurl = [NSURL URLWithString:url];
NSDictionary *postDict = [[NSDictionary alloc] initWithDictionary:postDataDic];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nurl];
[request setHTTPMethod:#"POST"]; // define the method type
[request setValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
// Peform the request
NSURLResponse *response;
NSError *error = nil;
dresponse = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
return dresponse;
}
This method prepares the Dictionary data for POST
- (NSData*)encodeDictionary:(NSDictionary*)dictionary {
NSMutableArray *parts = [[NSMutableArray alloc] init];
for (NSString *key in dictionary) {
NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *part = [NSString stringWithFormat: #"%#=%#", encodedKey, encodedValue];
[parts addObject:part];
}
NSString *encodedDictionary = [parts componentsJoinedByString:#"&"];
return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
}
Related
If you are familiar with Parse.com's Javascript SDK, this is what I am trying to do for my own server for my iOS app (Objective-c). I want to be able to send some a string to the function that is on my server, have the server run its function and then return a string to the app or some xml or JSON data.
Is this even possible?
I am new to doing something like this having an app make a call to a server. I have looked into opening a port on my server, but have been unable to find a way to receive data back to the iOS app. (I found this lib but its for OS X https://github.com/armadsen/ORSSerialPort). Also Im not sure if I have a function run with an open port on the server. So how can I set it up so I can make a call to my server and run a function?
Any help would be much appreciated.
You just need to POST data to your server.
Port could be anything you want.
Host your script with a domain url so that you can make network request publicly.
You can try this function:
-(NSData *)post:(NSString *)postString url:(NSString*)urlString{
//Response data object
NSData *returnData = [[NSData alloc]init];
//Build the Request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%lu", (unsigned long)[postString length]] forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
//Send the Request
returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
//Get the Result of Request
NSString *response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
bool debug = YES;
if (debug && response) {
NSLog(#"Response >>>> %#",response);
}
return returnData;
}
And here is how you use it:
NSString *postString = [NSString stringWithFormat:#"param=%#",param];
NSString *urlString = #"https://www.yourapi.com/yourscript.py";
NSData *returnData = [self post:postString url:urlString];
PHP
<?php
$response=array();
if(isset($_POST['param'])){
$response['success'] = true;
$response['message'] = 'received param = '.$_POST['param'];
}else{
$response['success'] = false;
$response['message'] = 'did not receive param';
}
$json = json_encode($response);
echo $json;
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.
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]);
I have the following code to get data from server;
-(void)loginForFaceBook
{
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:#"https://www.googleapis.com/auth/plus.me"
clientID:#"27615...6qdi60qjmachs.apps.googleusercontent.com"
clientSecret:#"Fs8A...u2PH"
keychainItemName:#"OAuth2 Sample:
Google+"
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
[[self navigationController] pushViewController:viewController
animated:YES];
}
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
if (error != nil) {
// Authentication failed (perhaps the user denied access, or closed the
// window before granting access)
NSLog(#"Authentication error: %#", error);
NSData *responseData = [[error userInfo] objectForKey:#"data"]; //
kGTMHTTPFetcherStatusDataKey
if ([responseData length] > 0) {
// show the body of the server's authentication failure response
// NSString *str = [[NSString alloc] initWithData:responseData
// encoding:NSUTF8StringEncoding];
// NSLog(#"%#", str);
}
// self.auth = nil;
} else {
// NSString *authCode = [NSString alloc]in;
NSMutableURLRequest * request;
request = [[NSMutableURLRequest alloc] initWithURL:[NSURL
URLWithString:#"http://api.kliqmobile.com/v1/tokens"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60] ;
NSLog(#"%#",auth);
NSLog(#"ho gya success %# :::: %# :::: %#", auth.accessToken,
auth.refreshToken, auth.code);
NSMutableURLRequest * response;
NSError * error;
request.URL = [NSURL URLWithString:#"http://api.kliqmobile.com/v1/tokens"];
NSString *post = [NSString stringWithFormat:#"
{\"token\":\"%#\",\"secret\":\"%#\",\"service\":\"%#\",\"handle\":\"%#\"}",
auth.accessToken,auth.code,#"google",nil];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded"
forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
error = nil;
response = nil;
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request
delegate:self];
[connection start];
}
I have implemented the NSURLConnection delegtes method and data is printing well like this
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
NSMutableURLRequest * response;
NSError * error;
NSLog(#"Did Receive Data %#", [[NSString alloc]initWithData:data
encoding:NSUTF8StringEncoding]);
NSMutableURLRequest * requestContacts;
requestContacts = [[NSMutableURLRequest alloc] initWithURL:[NSURL
URLWithString:#"http://api.kliqmobile.com/v1/contacts"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60] ;
[requestContacts setHTTPMethod:#"GET"];
[requestContacts setAllHTTPHeaderFields:headers];
error = nil;
response = nil;
NSData* data1 = [NSURLConnection sendSynchronousRequest:requestContacts
returningResponse:&response error:&error];
NSLog(#"WE GET THE REQUIRED TOKAN DATA %# :: %# :: %#", [[NSString alloc]
initWithData:data1 encoding: NSASCIIStringEncoding], error ,response);
}
but after that my app get crashed and it is giving following error;
[NSHTTPURLResponse release]: message sent to deallocated instance 0xcb51070.
please suggest me how to do this.
A couple of thoughts:
What is the intent of your didReceiveData method? There are a bunch of issues here:
You really shouldn't be doing a synchronous network request in the middle of a NSURLConnectionDataDelegate method.
You shouldn't be doing synchronous requests at all, but rather do them asynchronously.
What is the connection between receiving data and your creation of this new request? You're not using the data in the request, so why do it here?
The typical pattern is:
The didReceiveResponse should instantiate a NSMutableData object in some class property.
The only function of didReceiveData should be to append the received data to the NSMutableData. Note, this method may be called multiple times before all the data is received.
In connectionDidFinishLoading, you should initiate any next steps that you take upon successful completion of the request. If you wanted to do start another asynchronous network request when the initial request is done, do that here.
In didFailWithError, you obviously handle any failure of the connection.
When you call connectionWithRequest, you should not use the start method. Only use start when you use initWithRequest:delegate:startImmediately: with NO for the startImmediately parameter. Otherwise the connection starts automatically for you and you're only starting it a second time.
Unrelated to your original question, but your creation of post string cannot be right. You're missing a parameter value. Even better, rather than creating JSON manually, use NSDictionary and then use NSJSONSerialization to make the NSData object containing the JSON from this dictionary. That's much safer:
NSDictionary *params = #{#"token" : auth.accessToken,
#"secret" : auth.code,
#"service" : #"google",
#"handle" : #""};
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
Clearly, supply whatever you need for the handle value.
A tangential process-related observation, but I'm wondering if you're taking advantage of everything Xcode offers. For example, your declaration of response as a NSMutableURLRequest but then using that as a parameter to sendSynchronousRequest should have generated a compiler warning. The same thing is true with your stringWithFormat for your post string (my third point). That should have generated a warning, too.
Neither of these are immediately relevant, but I wonder if you are failing to heed any other compile-time warnings. These warnings are your best friend when writing robust code and I would recommend resolving all of them. To go a step further, you should also run the project through the static analyzer ("Analyze" on "Product" menu, or shift+command+B), and resolve anything it points out, too.
My App_Code/IGetEmployees.vb file
<ServiceContract()> _
Public Interface IGetEmployees
<OperationContract()> _
<WebInvoke(Method:="POST", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Wrapped, UriTemplate:="json/contactoptions")> _
Function GetAllContactsMethod(strCustomerID As String) As List(Of NContactNames)
End Interface
My App_Code/GetEmployees.vb file
<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
Public Function GetAllContactsMethod(strCustomerID As String) As List(Of NContactNames) Implements IGetEmployees.GetAllContactsMethod
Utilities.log("Hit get all contacts at 56")
Dim intCustomerID As Integer = Convert.ToInt32(strCustomerID)
Dim lstContactNames As New List(Of NContactNames)
'I add some contacts to the list.
Utilities.log("returning the lst count of " & lstContactNames.Count)
Return lstContactNames
End Function
NContactNames is a class with 3 properties.
So i am using ASP.NET web services to retrieve information from SQL server and pass it to my iPad in JSON format. I have a problem with parameter passing. So like you see i have 2 files IGetEmployees.vb and GetEmployees.vb. I am implementing the method GetAllContactsMethod. What's happening is the two lines in GetEmployees.vb file (Utilities.log), they never get logged. The function is not getting called at all.
My objective c code to call this function
NSString *param = [NSString stringWithFormat:#"strCustomerID=%#",strCustomerID];
jUrlString = [NSString stringWithFormat:#"%#",#"http://xyz-dev.com/GetEmployees.svc/json/contactoptions"];
jurl = [NSURL URLWithString:jUrlString];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:jurl];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[param dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(#" request string is %#",[[request URL] absoluteString]);
NSLog(#"Done");
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if(theConnection)
{
jData = [NSMutableData data];
NSError *jError;
NSMutableDictionary *json =[NSJSONSerialization JSONObjectWithData:jData options:kNilOptions error:&jError];
NSLog(#"%#",json); //Gets Here and prints (null)
NSLog(#"Done"); //prints this as well.
}
else
{
NSLog(#"No");
}
At the time of posting this code the "if" statement is true and (null) is printed followed by "Done"
The output of my absolute request is:
request string is http://xyz-dev.com/GetEmployees.svc/json/contactoptions
This is the first time i am writing json to accept parameters. So i might be missing something.What is it?Why is the function not getting called at all on the Visual Studio side. If you need more info please ask.Thanks...
this is the moethod in Objetive-C, for that.
-(void) insertEmployeeMethod
{
if(firstname.text.length && lastname.text.length && salary.text.length)
{
NSString *str = [BaseWcfUrl stringByAppendingFormat:#"InsertEmployee/%#/%#/%#",firstname.text,lastname.text,salary.text];
NSURL *WcfSeviceURL = [NSURL URLWithString:str];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:WcfSeviceURL];
[request setHTTPMethod:#"POST"];
// connect to the web
NSData *respData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// NSString *respStr = [[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:respData
options:NSJSONReadingMutableContainers
error:&error];
NSNumber *isSuccessNumber = (NSNumber*)[json objectForKey:#"InsertEmployeeMethodResult"];
//create some label field to display status
status.text = (isSuccessNumber && [isSuccessNumber boolValue] == YES) ? [NSString stringWithFormat:#"Inserted %#, %#",firstname.text,lastname.text]:[NSString stringWithFormat:#"Failed to insert %#, %#",firstname.text,lastname.text];
}
}
Before to run the code, test your URL with POSTMAN, is an app from Google Chrome.
regards.