Upload file via Soap message using MTOM in iOS - ios

I have found here Upload file via Soap message in detail. But i have another issue if there is large file in Soap then it creates memory issues cause of file loads in memory for sending via Soap message.
I read about MTOM (Message Transmission Optimisation Mechanism). "When you use MTOM/XOP to optimise a SOAP message, the XOP processing serialises it into a MIME Multipart/Related message. The XOP processing extracts the base64Binary data from the SOAP message and packages it as separate binary attachments within the MIME message, in a similar manner to e-mail attachments"
I have found how to use this approach in java here Soap with Attachments and MTOM in Java
Now i have two questions :-
By using MTOM/XOP approach in iOS we can reduce Or solve the
issue of memory as explaind above.
In programming How we can use MTOM/XOP approach in iOS.
Any help will be appriciated.Thanks in advance.

I have done same request using the Rest Kit.Rest kit allows to send attachment in MTOM Specification.
First thing you need is to download Restkit.
Following is the code snippet for the MTOM using the RestKit.
abv.h
#import "RestKit/RestKit.h"
RKObjectManager *man;
RKObjectLoader *loader;
abc.m
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
//Start Progress bar
RKParams * params = [[RKParams alloc] init];
UIImage *image=[UIImage imageNamed:#"zbar-samples.png"];
RKObjectManager *man;
NSData * fileData=UIImageJPEGRepresentation(image,0.7);
[params setValue:#"1234" forParam:#"encryptedToken"];
[params setValue:modelObj.docNameTobeSent
forParam:#"documentName"];
RKParamsAttachment * attachments = [params setData:fileData forParam:#"file"];
[attachments setMIMEType:#"image/jpeg"];
[attachments setFileName:[NSString stringWithFormat:#"%#.jpeg",modelObj.name]];
self.man = [RKObjectManager objectManagerWithBaseURL:YOUR URL];
self.loader = [self.man loadObjectsAtResourcePathUsingPOSTRPC:#"upload.form" objectMapping:nil PostParams:params delegate:self];
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error
{
//Handle fail error
//stop Progress bar
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects
{
NSLog(#"%#",#"didLoadObjects");
}
- (void)objectLoaderDidFinishLoading:(RKObjectLoader*)objectLoader
{
NSLog(#"%#",#"objectLoaderDidFinishLoading");
//stop Progress bar
}
- (void)objectLoaderDidLoadUnexpectedResponse:(RKObjectLoader*)objectLoader
{
NSLog(#"%#",#"objectLoaderDidLoadUnexpectedResponse");
//stop Progress bar
}

Related

ConnectionID is in incorrect formate. SignalR

I usesignalR latest library. I downloaded signalR library from gitHub SignalR gitHub link and installed pod file in my app. I am working on iOS end. I don't know about asp.net. The only url is provided to me for integration. Here is my code
__weak SRConnection *connection = [SRConnection connectionWithURL:SIGNALR_PATH];
[connection addValue:[[NSUserDefaults standardUserDefaults] objectForKey:kAccessToken] forHTTPHeaderField:#"MyAuthentication"];
connection.received = ^(NSString * data) {
NSLog(#"%#",data);
};
connection.started = ^{
[connection send:#"hello world"];
};
[connection start];
Connection open successfully but When I get try to send message it gives me an error "The ConnectionId is in incorrect format".
I am using latest library of signalR. I don't know what I need to authorised. Is only url enough for that? Or will need to add accessToken that I get on login?.
Please help me what I need for integrating signalR. I searched a lot but couldn't find any clear information.

How to call xml-rpc webservice using objective c

Suppose, the webservice provider's server exposing the webservice in the form http://example.com:8000/api
What is best framework or library to access the webservice in ios 7 project
There are a few marshaling frameworks that support generating an object-graph from XML, however I would simply go for the following:
Invoke the service endpoint. My favorite library is BBHTTP, however you could use AFNetworking, NSURLConnection with gcd or whatever you prefer for asynch network calls.
Extract the relevant contents of the XML payload onto your use-case specific payload object using RaptureXML
I recommend having use-case specific payload objects because they model exactly what is needed for a given service invocation - supporting the notion of contract-first development. This allows you to change you internal model without effecting the integration to external systems. Similarly the external API can change without effecting your model.
You can create a category method on RXMLElement to return the element mapped to a use-case-specific object. A typical mapping usually takes just a handful of lines of code to marshal from wire-format to your payload object for the service invocation.
Here's an example (the code that I took it from wanted the payload wrapped in a SOAP envelope - just ignore that bit).
- (void)request:(MyUseCaseRequstPayload*)request onComplete:(void (^)(MyResponsePayload*))onSuccess
onError:(void (^)(NSError*))onError;
{
//Even more XML! You can stick your payload inside an envelope if you want
SoapEnvelope* envelope = [SoapEnvelope envelopeWithContent:[request xmlString]];
[[BBHTTPRequest postToURL:_serviceUrl data:[envelope data] contentType:#"text/xml"] execute:^(BBHTTPResponse* response)
{
RXMLElement* element = [RXMLElement elementFromXMLData:[response content]];
MyResponsePayload* response = [[element child:#"elementToBeMapped"] asMyObjectType];
if (onSuccess)
{
onSuccess(response);
}
} error:^(NSError* error)
{
LogDebug(#"Got error: %#", error);
if (onError)
{
onError(error);
}
}];
}

Survey application with offline capabilities and how to capture the data from multiple ipads to one?

I am trying to build a Survey application where the surveys will be taken offline on multiple ipads and when these ipads are online they are going to upload the data(survey answers) to our servers? I am really struggling how to send the survey to multiple ipads and more importantly to capture from different ipads to one source ?
I need help to clear my architecture part and I need some examples to do the coding part. Do you know anything similar?
What are you ideas?
Many Thanks in advance,
Arda
Create a web server to accept and send survey questions and answers.
I would envision an app that goes like this:
1) Slave iPads makes a HTTP POST request to server asking for the survey
This is usually done using a networking library for iOS like MKNetworkKit or AFNetworking. The general process is to:
create a NSDictionary of key-value pairs to form the HTTP POST request
submit the data through a block construct with completion handler
So something like:
MKNetworkOperation *op = [engine operationWithURLString:#"http://www.mywebserver.com/api/fetchQuestions"
params:nil
httpMethod:#"POST"];
2) Server receives request, grabs all survey questions in database and return JSON encoded questions to slave ipads.
I'm not sure what platform your web server is on but in the past, I used Symfony 2.0 which is a PHP web framework.
It provides very helpful tools like Doctrine (an Object Relational Mapper or ORM) to let me work with my MySQL data as if they're programming objects.
So my general process for fetching data would be something like:
// pseudo php function codes
public function sendSurveyQuestionAction()
{
$repository = $this->getDoctrine()->getRepository('MyAppBundle:Survey');
$query = $repository->createQueryBuilder('query')->getQuery();
$arrObjs = $query->getResult();
$arrObjDatas = NULL;
foreach($arrObjs as $obj)
{
$arrObjDatas[] = $obj->toArray();
}
$response = new Response(json_encode(array('data' => $arrObjDatas)));
$response->headers->set('Content-Type', 'application/json');
$return $response;
}
This would return all survey in JSON format, ready to be parsed by your master iPad app.
3) Users on slave iPads fill in the questions through the app UI and submits. The app saves
the data to disk, checks for a working internet connection before sending data back to server.
Submitting the answer is very similar grabbing the questions, so your iOS code should be something like:
// ------------------------------------------------------------------------------------
// store all question-answers into a dictionary to be submitted as HTTP POST variables
// obviously, you wouldn't create it here, this is just example code, you would likely
// have stored your questions and answers when user presses 'finish' button
// ------------------------------------------------------------------------------------
NSMutableDictionary *paramDictionary = [[NSMutableDictionary alloc] init];
[paramDictionary setObject:#"5" forKey:#"q1"];
[paramDictionary setObject:#"10" forKey:#"q2"];
[paramDictionary setObject:#"15" forKey:#"q3"];
// this helps your web server know how many question-answers to expect, or you could hard code it into your business logic
[paramDictionary setObject:[NSNumber numberWithInteger:3] forKey:#"numberOfQA"];
MKNetworkOperation *op = [engine operationWithURLString:#"http://www.mywebserver.com/api/submitAnswers"
params:paramDictionary
httpMethod:#"POST"];
This will submit your answers for each of your question. You may have noticed I used q1, q2, q3.
These are for your web server code to identify each questions and extract the respective answers from them.
4) Server receives finished answers and commit them to database
So if you were using Symfony 2.0 PHP code, then something like:
// pseudo php function
public function saveAnswersAction()
{
$numOfQA = $_REQUEST['numberOfQA'];
for($i = 0; $i < $numOfQA; $i++)
{
// ----------------------------------------------------------------------
// looping through all the questions such as q1, q2, q3, q4, q5....
// by appending the counter variable to the question identifier
// ----------------------------------------------------------------------
$currentAnswer = $_REQUEST['q'.$i];
// use Doctrine to create new answer entities, and fill in their data
$answerEntity.answer = $currentAnswer;
$surveyEntity->addAnswerEntity($answerEntity);
// mark survey as complete so we can fetch all 'completed' surveys later
$surveyEntity.complete = true;
}
// tell Doctrine to commit changes to MySQL Database
// return HTTP OK status message
}
5) Now all that's left is for your master iPad app to make a HTTP POST request to get all surveys.
The process is the same with your iOS code making a HTTP POST requesting for all 'completed' survey entities from your web server.
The web server grabs them and return them as JSON encoded data.
Your app then receives the completed surveys with question answer like this:
surveys
{
{
questionNumber: 1,
questionAnswer: "5"
},
{
questionNumber: 2,
questionAnswer: "10"
},
{
questionNumber: 3,
questionAnswer: "15"
}
}
Now you use JSONKit to parse this JSON data. You should end up with a NSDictionary from JSONKit.
You can then go something like:
// pseudo code
-(void)displayCompletedSurveys
{
[MKNetworkOperationEngine doRequest:
...
^completionBlock {
// parse JSON data
NSDictionary *surveyData = [JSONKit dictionaryFromJSONData:data)
NSEnumerator *enumerator = [surveyData enumerator];
NSDictionary *currentQuestion = nil;
while([enumerator nextObject] != nil)
{
// do something with each of your question-answer e.g. show it on screen
}
}];
}
Points To Consider
Most of the code above are pseudo-codes. Your final real code would probably be much more in depth.
You'll need to build some master login into your app to prevent everyone from seeing the completed surveys.
Some Extra Information You Should Know
Here are some extra information to help you
JSONKit for fast JSON data decoding from your web server
MKNetworking or AFNetworking to submit your data to your web server
You need to know how to write web services to handle accepting the survey answers. I recommend learning a web framework like Symfony 2.0
Hope that helps.

How to handle chunking while streaming JSON data to NSURLConnection

I have a web server that is streaming JSON results back asynchronously to an iOS client. The client is connecting using NSURLConnection and I access the data from the method:
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData)
Data is currently coming back in 1024 byte chunks. However, I'm not sure how to tell if when I receive data if the message was complete other than appending all the data I receive to a string and try to parse it to JSON each time. This method seems quite error prone - is there a better way to handle this? Something that would mark in the headers or something when a full response has been sent?
You have two ways
first & better way is implement connectionDidFinishLoading: NSURLConnectionDataDelegate delegate which will trigger when a connection has finished loading successfully.
Second way is handling it manually as follows.
You can do the following things in Web-server side,
Step1: Send the below informations first before starting to send the original data.
a.Number of Chunks.[totalSize/1024] (mandatory).
b.TotalSize(not mandatory).
You can do the following things in Client side side,
Step1: Store the above informations.
Step2: Write the below code
#property (nonatomic,assign) int chunkNumber;
#property (nonatomic,strong) NSData *receivedData;
Self.chunkNumber = 1;
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData)myata{
if(self.chunkNumber != Number of Chunks)
{
if(!self.receivedData)
{
//allocate and initialize self.receivedData
}
[self.receivedData appendData:myData];
}
else
{
//completed . do whatever with self.receivedData.
//if you want to validate, just check the self.receivedData size with TotalSize
self.chunkNumber = 1;
}
}
In the NSURLConnectionDataDelegate, there is a method connectionDidFinishLoading: that should be called when the server is done sending. You can also retrieve the expected length in didReceiveResponse but that is not reliable and required server side support.

Alternative ways to send email without UI from ipad or iphone

I see there are many ways to send email in the background (without UI) in iOS devices and without using MFMailComposeViewController class. Most popular examples are fill an online form and press submit button. Here are the most popular methods i see in stackoverflow..
(1) Using your own SMTP client. This approach is working for me but in my private network but not working in my company premises as in company network I am not allowed to use gmail (public emails) and don't have SMTP details of our company mail server. I am struck here in this approach.
(2) Using CTCoreMessage & Three20 Framework (open source). But here I am not able to find where to download this framework other than git, where my pc VLAN not allowing GIT. Could somebody help me to find out the Three20 Framework downloadable location and share me an example code.
(3) Using HTTP Post: Send your email body to the server and delegate the email sending to the HTTP Server. If this is simple then can somebody help me how to setup your own HTTP Server for sending emails.
Could anybody help in finding any working sample code. I am at end of my project delivery. Posted this long back. No replies till now. Could anybody help me please..
I would look into using Mailgun, it will make sending emails much easier and handles up to 10k a month for free. They allow you to use their subdomain if you dont have your own, but can easily setup your own to work with theirs.
Its as easy as installing up a cocoapod and adding 5 lines of code or so.
I might be able to provide some help for the third option, using HTTP Post, since I did implement it once in a project.
First, I used this nice and simple iOS class to take care of the posting for me.
Then, the following iOS code snippet should show you how it's done
NSString* from = #"sender#email";
NSString* to = #"receiver#email";
NSString* mailCc = #"cc#email";
NSString* message = #"my message"
NSString* subject = #"my subject";
NSURL* url = [NSURL URLWithString:#"http://yourtestsite.com/my_email_script.php"];
//these are $_POST variables sent, so 'from' would be $_POST['from']
NSArray *keys = [[NSArray alloc] initWithObjects:#"from", #"to", #"cc", #"subject", #"message", nil];
NSArray *objects = [[NSArray alloc] initWithObjects:from, to, mailCc, subject, message, nil];
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
NSMutableURLRequest* request = [SimplePost urlencodedRequestWithURL:url andDataDictionary:dictionary];
NSURLResponse* response = [[NSURLResponse alloc] init];
NSError* error = [[NSError alloc] init];
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
NSString* result = [[NSString alloc] initWithData:returnData encoding:NSStringEncodingConversionAllowLossy];
//I'm checking for 1 because my php script was set to write 1 to the page in case of success and 0 otherwise, so this is simply my implementation
if([result isEqualToString:#"1"]) {
NSLog(#"success");
} else {
NSLog(#"error");
}
For the PHP file, this should do the trick
$from = filter_var($_POST['from'], FILTER_SANITIZE_EMAIL);
$to = filter_var($_POST['to'], FILTER_SANITIZE_EMAIL);
$cc = filter_var($_POST['cc'], FILTER_SANITIZE_EMAIL);
$subject = htmlspecialchars(utf8_decode($_POST['subject']));
$message = utf8_decode($_POST['message']);
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
// Additional headers
$headers .= 'From: ' . $from . "\r\n";
$headers .= 'Cc: ' . $cc . "\r\n";
// Mail it
if(mail($to, $subject, $message, $headers)) {
echo("1");
} else {
echo("0");
}
Keep in mind, I'm no PHP expert, so that code might be improved, especially on the security part.
[edit]
PHP mailing should already be enabled in most major managed hosting solutions, be it a cheap shared account, a VPS or a dedicated server. But if you plan to send A LOT of emails with this method, then a dedicated server is recommended.
However, there is a limit of emails you can send and better options than the mail function. You can find more info about this here.
[later edit]
It seems the author deleted the SimplePost class. However, the same author made an alternative which should help, called SimpleHTTPRequest. The rest should remain the same

Resources