I'm trying to convert my Android post request to iOS (Swift). Currently, this is the Android code:
JSONObject json = new JSONObject();
json.put("major", Major);
json.put("minor", Minor);
json.put("uuid", UUID);
json.put("userid", id);
int TIMEOUT_MILLISEC = 10000; // = 10 seconds
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
HttpClient client = new DefaultHttpClient(httpParams);
HttpPost request = new HttpPost("http://" + ipAddress + ":8080/");
request.setHeader("Content-Type", "application/json");
request.setEntity(new ByteArrayEntity(
json.toString().getBytes("UTF8")));
HttpResponse response = client.execute(request);
This works perfectly fine.
However, when I try to convert it to Swift, the server doesn't receive anything even though I know that it's executing the request.
Swift:
var request = NSMutableURLRequest(URL: NSURL(string: URLString)!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var params = ["major": "1", "minor": "2", "uuid": "00000000-1111-2222-3333-444444444444", "userid": "3"] as Dictionary<String, String>
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let task = session.dataTaskWithRequest(request) { data, response, error in
guard data != nil else {
print("no data found: \(error)")
return
}
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
let success = json["success"] as? Int
} else {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
}
} catch let parseError {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
}
}
Any help or direction would be nice. Thanks.
Edit 1: A task.resume() got me a response from the server. However, if anyone knows how to convert "request.setEntity(new ByteArrayEntity(json.toString().getBytes("UTF8")));" in Swift, that would be really helpful.
#Naga Krishnamraju
For your second concern where need to parse json string to object you can do that using following way
if(response != nil)
{
// Print out reponse body
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
//print("****** response data = \(responseString!)")
do {
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
print(json ?? "Error")
print("responseString :-%#",responseString ?? "error");
DispatchQueue.main.async {
if((json?.count)! > 0)
{
//here you get json as dictionary now you can have your implementation
}
}
}catch
{
print(error)
failure(error as NSError);
}
}
Did you forget to add task.resume ?
task.resume() after block will do the job
Related
enter image description hereI have created REST API in ASP.NET with http://server/token as URL.
The header having
content-type: application/x-www-form-urlencode
The body have grant_type as password, username and password will get json data with token.
For further data access token can be used above method works with postman
I need to implement a client in Android Studio or Xamarin.
as urls in postman is "example.com/token"; , then in Header Key value pais for content type as ("Content-Type:application/x-www-form-urlencoded) and in body key value pair as (grant_type:password, username:email,password:pass) and after send the response is in json format as follows { "access_token": "token", "token_type": "bearer", "expires_in": 1209599, "userName": "mail#gmail.com", ".issued": "Fri, 09 Dec 2016 19:19:18 GMT", ".expires": "Fri, 23 Dec 2016 19:19:18 GMT" }
this same needed to be done in android
Include in your dependencies System.Net.Http (requires Xamarin profile 111) and then you can use that to create a HttpClient and request the token via HTTP POST (akin to what you were doing in Postman) like this..
_client = new HttpClient();
var uri = new Uri("http://server/token");
var content = new FormUrlEncodedContent(
new List<KeyValuePair<string, string>> {
new KeyValuePair<string, string>("username", _username),
new KeyValuePair<string, string>("password", _password),
new KeyValuePair<string, string>("grant_type", "password")
});
HttpResponseMessage response = await _client.PostAsync(uri, content);
Where _username and _password are strings.
Then read the response out by converting it into a Dictionary or any other reasonable alternative approach to parsing the JSON response.
if (response.StatusCode == HttpStatusCode.OK) {
var jsonContent = await response.Content.ReadAsStringAsync();
var responseDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonContent);
if (responseDict.ContainsKey("access_token"))
_token = responseDict["access_token"];
}
Then once you have the token, you can include it as a default authorization value for all headers from that HttpClient instance!
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);
Where _token is the token as it's encoded string, e.g. "eyJ0eXAiOiJKV1QiLC..."
Just implemented this and to verify it's correctness - I ran it against a production environment I have set up to verify using JWTs and it worked a charm.
this works, it looks ugly but you can change it
var authCredentials = "grant_type=password&username=" + WebUtility.UrlEncode(LoginBindingModel.Email) + "&password=" + LoginBindingModel.Password;
string response = await Client.MakePostFormRequest("token", authCredentials);
public static async Task<string> MakePostFormRequest(string url, string data)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(BaseUrl + "token");
// Set the Method property of the request to POST.
request.Accept = "*/*";
request.Method = "POST";
// Create POST data and convert it to a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(data);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
//request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = await request.GetRequestStreamAsync().ConfigureAwait(false);
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Dispose();
// Get the response.
WebResponse response = await request.GetResponseAsync().ConfigureAwait(false);
// Display the status.
//Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
//Console.WriteLine(responseFromServer);
// Clean up the streams.
TokenViewModel TokenViewModel = JsonConvert.DeserializeObject<TokenViewModel >(responseFromServer);
VariablesGlobales.Token = TokenViewModel.access_token;
VariablesGlobales.LoginStamp = TokenViewModel.LoginStamp;
reader.Dispose();
dataStream.Dispose();
response.Dispose();
return responseFromServer;
}
catch (Exception ex)
{
return "";
}
}
And when you want to authenticate your request
public static async Task<string> MakePostRequest(string url, string data)
{
var result = "";
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(BaseUrl + url);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
if (VariablesGlobales.Token != "")
{
httpWebRequest.Headers[HttpRequestHeader.Authorization] = "Bearer " + VariablesGlobales.Token;
}
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)))
{
streamWriter.Write(data);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)(await httpWebRequest.GetResponseAsync().ConfigureAwait(false));
if (httpResponse.StatusCode.ToString() == "OK")
{
result = httpResponse.StatusCode.ToString();
}
else
{
result = "";
}
}
catch (Exception ex)
{
result = "";
}
return result;
}
}
I am working at the REST API for a new Social Network Android App at the moment using Spring Android for the Client and Spring Boot for the Server.
I am having trouble securing the Server using Spring Security, because i don't understand how to use it properly. After reading tons of sample apps i gave up on spring security and found this tutorial on how to secure APIs using Jersey.
Instead of javascript i am using the Jersey Client API to test the implementation
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/demo-business-resource/login");
Invocation.Builder invoBuilder = target.request();
invoBuilder.header("service_key", "3b91cab8-926f-49b6-ba00-920bcf934c2a");
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("username", "username2");
formData.add( "password", "passwordForUser2");
Response response = invoBuilder.post(Entity.form(formData));
System.out.println(response);
response.getEntity();
The POST request is successful, but i cant get the JSON object which should be the Entity of the Response. response.getEntity(); returns a HttpUrlConnector Object.
Here the related Server Code
#POST
#Path( "login" )
#Produces( MediaType.APPLICATION_JSON )
public Response login(
#Context HttpHeaders httpHeaders,
#FormParam( "username" ) String username,
#FormParam( "password" ) String password ) {
DemoAuthenticator demoAuthenticator = DemoAuthenticator.getInstance();
String serviceKey = httpHeaders.getHeaderString( DemoHTTPHeaderNames.SERVICE_KEY );
try {
String authToken = demoAuthenticator.login( serviceKey, username, password );
JsonObjectBuilder jsonObjBuilder = Json.createObjectBuilder();
jsonObjBuilder.add( "auth_token", authToken );
JsonObject jsonObj = jsonObjBuilder.build();
return getNoCacheResponseBuilder( Response.Status.OK ).entity( jsonObj.toString() ).build();
} catch ( final LoginException ex ) {
JsonObjectBuilder jsonObjBuilder = Json.createObjectBuilder();
jsonObjBuilder.add( "message", "Problem matching service key, username and password" );
JsonObject jsonObj = jsonObjBuilder.build();
return getNoCacheResponseBuilder( Response.Status.UNAUTHORIZED ).entity( jsonObj.toString() ).build();
}
}
private Response.ResponseBuilder getNoCacheResponseBuilder( Response.Status status ) {
CacheControl cc = new CacheControl();
cc.setNoCache( true );
cc.setMaxAge( -1 );
cc.setMustRevalidate( true );
return Response.status( status ).cacheControl( cc );
}
I am new to Jersey and i only want to use it to generate the Authentication Token, because i get 404 Not Found errors using Spring. (I am working with spring-jersery )
Here my Spring approach of the client
RestTemplate template = new RestTemplate();
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("service_key", "3b91cab8-926f-49b6-ba00-920bcf934c2a");
MultiValueMap<String,String> formData=new LinkedMultiValueMap<String,String>();
formData.add("username", "username2");
formData.add( "password", "passwordForUser2");
Model_LoginProfile log = new Model_LoginProfile();
log.setLoginName("username2");
log.setPassword("passwordForUser2");
HttpHeaders requestHeaders=new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.set("service_key", "3b91cab8-926f-49b6-ba00-920bcf934c2a");
HttpEntity<Model_LoginProfile> requestEntity = new HttpEntity<Model_LoginProfile>(log, requestHeaders);
ResponseEntity<String> result = template.postForEntity("http://localhost:8080/demo-business-resource/login", requestEntity, String.class);
}
Maybe someone has a fix for that as well. :)
Thanks in advance
I have implemented ASP.NET WebApi and consumed in Android application with HTTPPOST. Parameter less methods are calling perfectly but method with parameters not working while it is working fine with Advanced Rest Client in Google Chrome also working perfectly with HTTP GET.
Caller Code in Android:
String url = "http://192.168.15.3/api/user"
HttpPost postMethod = new HttpPost(url);
postMethod.setHeader("Content-Type", "application/json; charset=utf-8");
postMethod.setHeader("Accept", "*/*");
postMethod.setHeader("Accept-Encoding", "gzip, deflate");
postMethod.setHeader("Accept-Language", "en-US,en;q=0.8");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", "1"));
DefaultHttpClient hc = new DefaultHttpClient();
HttpResponse response;
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
response = hc.execute(postMethod);
HttpEntity entity = response.getEntity();
InputStream inStream = entity.getContent();
String result = convertStreamToString(inStream);
Log.e("Result: ", result);
Controller:
public class UserController : ApiController
{
UserCredentials[] users = new UserCredentials[]
{
new UserCredentials { User_ID = "1", User_Name = "testuser", Password = "test", First_Name = "Test", Last_Name = "User",
Email = "testuser#dummy.com", Phone ="123456789", Mobile = "123456789", User_Type = "user" },
new UserCredentials { User_ID = "2", User_Name = "testuser2", Password = "test", First_Name = "Test", Last_Name = "User",
Email = "testuser2#dummy.com", Phone ="123456789", Mobile = "123456789", User_Type = "user" }
};
[AcceptVerbs("POST")]
public IEnumerable<UserCredentials> GetAllUsers()
{
return users;
}
[AcceptVerbs("POST")]
public IHttpActionResult GetUser(string id)
{
var user = users.FirstOrDefault((p) => p.User_ID.Equals(id));
if (user == null)
{
return NotFound();
}
return Ok(user);
}
}
Error:
{"Message":"No HTTP resource was found that matches the request URI 'http://192.168.15.3/api/user'.","MessageDetail":"No action was found on the controller 'User' that matches the request."}
It is throwing an error because your controller does not have any matching httppost method. You are trying to post data to method which accepts GET request.
WebApi works on convention based method names. Your methods starts with "Get" so it will map requests in below manner :
Get All users - GET - /api/users
Get user by Id - GET - /api/users/id
So you can call them using HttpGet request and not POST.
I am having trouble figuring out why i'm getting a JSON exception while I am parsing my JSON object. I am getting(Http GET) the JASON from a URL. Here is all the relevant code, let me know if you need to see any more of the code
The doInBackground Async method:
#Override
protected Void doInBackground(Void... arg0)
{
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(URL,ServiceHandler.GET);
Log.w("Rakshak", "the jaon String is:"+jsonStr);// this prints the JASON in the log and it looks fine
// I am not pasting it in coz it is HUGE
if (jsonStr != null)
{
try {
JSONObject jsonObj = new JSONObject(jsonStr);
Log.w("Rakshak", "in the try before the JASON");
// Getting JSON Array node
kingtide = jsonObj.getJSONArray("JASON");
// looping through All Kingtide events
for (int i = 0; i < kingtide.length(); i++)
{
JSONObject k = kingtide.getJSONObject(i);
String date = "Date Range:"+k.getString(KEY_DATE);
String lat = k.getString(KEY_LAT);
String lng = k.getString(KEY_LNG);
String loc = "Location of the Kingtide:"+k.getString(KEY_LOC)+", "+k.getString(KEY_STATE);
String temp_Time = k.getString(KEY_TIME);
String[] time_parts = temp_Time.split("T");
String time = "Kingtide at:"+time_parts[1]+" "+getYear(time_parts[0]);
// tmp hashmap for single kingtide event
HashMap<String, String> kt = new HashMap<String, String>();
// adding each child node to HashMap key => value
kt.put(KEY_DATE, date);
kt.put(KEY_LAT, lat);
kt.put(KEY_LNG, lng);
kt.put(KEY_LOC, loc);
kt.put(KEY_TIME, time);
Log.w("Rakshak", KEY_DATE+KEY_LAT+KEY_LNG+KEY_LOC+KEY_TIME);
// adding the kingtide to the kingtide hash map. this will be used to fill up the list view
kingTideList.add(kt);
}
} catch (JSONException e) {
Log.e("Rakshak", "JSONException "+e.getMessage()); // this prints "JSONException Value [{"Latitude":-19.9078861,"Location":"Abbot....." and the rest of the JASON(all of it)
}
}
else
Log.w("Rakshak", "JASON string is null");
return null;
}
the Service handler class:
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* #params - http request params
* */
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
Log.e("Rakshak", "UnsupportedEncodingException "+e.getMessage());
} catch (ClientProtocolException e) {
Log.e("Rakshak", "ClientProtocolException "+e.getMessage());
} catch (IOException e) {
Log.e("Rakshak", "IOException "+e.getMessage());
}
Log.w("Rakshak", "In the service handeler: this is a test");
return response;
}
}
Part of the stacktrace:
03-14 10:09:56.861: E/Rakshak(7037): JSONException Value [{"Latitude":-19.9078861,"Location":"Abbot Point","Longitude":148.08467259999998,"DateRange":"1–3 January 2014","HighTideOccurs":"2014-01-02T09:47:00","State":"QLD"},{"Latitude":-27.477819,"Location":"Brisbane
The URL for the JASON file is "http://witnesskingtides.azurewebsites.net/api/kingtides"
NOTE: I know it looks like a XML file but it is JASON . Just run it through a validator/viewer and see for your self if you want.
My question in why am I getting a JASON exception and how do I fix it.
The Response you are getting is XML response and you are trying to parse it as JSON.
Refer this tutorial on XML parsing
When getting the contents, I get this back (part of it):
[
{
"Location": "Abbot Point",
"State": "QLD",
"HighTideOccurs": "2014-01-02T09:47:00",
"DateRange": "1–3 January 2014",
"Latitude": -19.9078861,
"Longitude": 148.08467259999998
},
{
"Location": "Brisbane Bar",
"State": "QLD",
"HighTideOccurs": "2014-01-02T10:16:00",
"DateRange": "1–3 January 2014",
"Latitude": -27.477819,
"Longitude": 153.01889119999998
},
...
]
This means that your object is already an array. Try to change this in your code:
//JSONObject jsonObj = new JSONObject(jsonStr);
Log.w("Rakshak", "in the try before the JASON");
// Getting JSON Array node
kingtide = new JSONArray(jsonStr);
since the returned jsonStr is already an array (and not an object with an array-attribute called "JASON").
Confirmed that the service is in fact returning a JSON response (you can check this in a tool like Fiddler). The default response from the API is JSON. The reason you are seeing XML by clicking the link provided in the question is because the browser is requesting a content type of application/xml, so that is what the browser shall receive.
I don't know the answer to your actual problem though, as the JSON seems to validate in everything I've tried. Maybe an incompatibility with the Android parser?
I'd suggest trying a different parser in your Android app to parse the response from the server. I've used Gson before which was easy to set up and use.
http://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html
The service returns an array of objects so instead of
JSONObject jsonObj = new JSONObject(jsonStr);
use
JSONArray jsonArray = new JSONArray(jsonStr);
and continue from there.
Update: Disregard my answer below...
Not to burst your repeated notion of the fact that it is JSON, it is not.
The response that your code gets back is plain XML.
However,
The resource you are requesting ( http://witnesskingtides.azurewebsites.net/api/kingtides ) supports both XML formatted responses and JSON formatted responses. It probably all has to do with the Accept headers that are missing from your request in your code or are set to application/xml or text/xml or something similar in your ServiceHandler.
When your code gets the response of the server, the server does not find an Accept header and returns XML format.
When the JSON validator sites, that you mention, request the same URL, they likely add an Accept header that tells the server to return the response in JSON format.
I'm not sure how the ServiceHandler class works, but when you create a GET request you should add the HTTP Header with name Accept and value application/json and then issue the request. You now will get JSON back instead of XML.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
I am sending post request from android to the url using httpclient like this one below -
String url = "http://www.myurl.com/test.php?format=json";
Now I am getting response back in form of plist instead of json, which is default type of response from php file if no format query string is described in url.
Can we specify query string in url while posting? It looks like php file is not getting format query string.
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("method", "add"));
nameValuePairs.add(new BasicNameValuePair("device_id", "123"));
nameValuePairs.add(new BasicNameValuePair("device_token", "3221"));
nameValuePairs.add(new BasicNameValuePair("session_id", "1212"));
nameValuePairs.add(new BasicNameValuePair("event_id","12345" ));
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url); httppost.addHeader("Content-Type","application/x-www-form-urlencoded");
httppost.addHeader("Accept","application/json");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
HttpResponse response = httpclient.execute(httppost);
/* Checking response */
if (response != null) {
InputStream in = response.getEntity().getContent();
String a = convertStreamToString(in);
Log.i("Read from Server "+response.getStatusLine().getStatusCode(), a);
}else{
Log.i("response is ", "null");
}
Thanks
It's impossible to know without seeing your server code, but your server may not like that you're combining HTTP POST parameters in your request body with GET parameters in the URL. Try putting
nameValuePairs.add(new BasicNameValuePair("format","json" ));
into the section where you're building up the request parameters instead and see what happens.
Here is my server code
<?php
error_reporting( E_ALL );
ini_set( 'display_errors', 'on' );
if (file_exists("lib")) {
require_once('lib/CFPropertyList-1.0.4/CFPropertyList.php');
include_once("lib/iCon_db_manager.php");
include_once("lib/iConLib.php");
} else {
require_once('../lib/CFPropertyList-1.0.4/CFPropertyList.php');
include_once("../lib/iCon_db_manager.php");
include_once("../lib/iConLib.php");
}
global $_POST;
$method = $_POST["method"];
$event_id = $_POST["event_id"];
if (isset($_POST["session_id"])) {
$session_id = $_POST["session_id"];
}
$device_id = $_POST["device_id"];
$device_token = $_POST["device_token"];
if (strcmp($method, "add") &&
strcmp($method, "delete") &&
strcmp($method, "show")) {
retStatus(1, "Invalid method. Allowed values are add/delete/show");
exit;
}
if (!isset($event_id) || !isset($device_id) || !isset($device_token)) {
retStatus(1, "Event ID, Device ID and Device Token are required");
exit;
}
$scheduleInfo["event_id"] = $event_id;
$scheduleInfo["device_id"] = $device_id;
$scheduleInfo["device_token"] = $device_token;
if (!isset($session_id)) {
// if session_id is not specified either the method is show alerts
$session_id = "";
}
if ($session_id != "") {
$scheduleInfo["session_id"] = $session_id;
}
$iConDBMgr = new iConDBManager();
if (!strcmp($method, "add")) {
if ($session_id == "") {
retStatus(1, "Session ID is required for add");
exit;
}
$schedule = $iConDBMgr->getRecord('iconmyschedule', $scheduleInfo);
if (count($schedule) == 0) {
$iConDBMgr->insertRecord('iconmyschedule', $scheduleInfo);
retStatus(0, "Success");
exit;
} else {
retStatus(2, "You already have this item in your schedule");
exit;
}
} else if (!strcmp($method, "delete")) {
$iConDBMgr->deleteRecord('iconmyschedule', $scheduleInfo);
retStatus(0, "Success");
exit;
} else {
$items = $iConDBMgr->getRecord('iconmyschedule', $scheduleInfo);
$plist = new CFPropertyList();
$plist->add( $dict = new CFDictionary() );
$dict->add( 'event_id', new CFString($event_id));
$dict->add( 'device_id', new CFString($device_id));
$dict->add( 'device_token', new CFString($device_token));
$dict->add('sessions', $sessArray = new CFArray());
if (count($items) != 0) {
foreach ($items as $item) {
$sessArray->add(new CFString($item{"session_id"}));
}
}
retResult($plist);
}
?>