1

I am creating OneNote page using OneDrive iOS SDK from my iOS application. This is the code i did for post request for multiple image.

NSMutableArray *selecedFileNames = [[NSMutableArray alloc] init];
NSString *date = [self formatDate];
NSString *start = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
                   "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en-us\">\r\n"
                   "<head>\r\n"
                   "<title>Created By</title>\r\n"
                   "<meta name=\"created\" content=\"%@\" />\r\n"
                   "</head>\r\n"
                   "<body>\r\n"
                   "<p>This is <b>Photo</b> <i>Created</i> note.</p>\r\n",date];

for (int i = 0; i<self.selectedImages.count; i++) {

    self.imgObject = (ImageObjects *)[self.selectedImages objectAtIndex:i];

    FileModel *fileModel = [FileModel new];
    fileModel.fileData = self.imgObject.image_data;
    fileModel.fileName =  self.imgObject.imageName;
    fileModel.fileType = FileTypeImage;

    self.filePath = fileModel.getFileName;

    NSString *trimmedString = [self.filePath  stringByReplacingOccurrencesOfString:@" " withString:[NSString stringWithFormat:@"%d",i]];
    self.filePath = [trimmedString  stringByReplacingOccurrencesOfString:@":" withString:@""];

    NSString *middle = [NSString stringWithFormat:@"<img src=\"%@\" alt=\"image\" width=\"500\">\r\n",self.filePath];

    [selecedFileNames addObject:self.filePath];
    start = [start stringByAppendingString:middle];

}

start = [start stringByAppendingString:@"</body>\r\n"
         "</html>\r\n"];

NSString *boundary = [self generateBoundaryString];

NSString *pagesEndpoint = [NSString stringWithFormat:@"sections/%@/pages", selectedSectionId];
NSString *fullEndpoint = [serviceRootUrl stringByAppendingString:pagesEndpoint];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:[NSURL URLWithString:fullEndpoint]];
[request setHTTPMethod:@"POST"];

// set content type
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];

NSMutableData *body = [NSMutableData data];


[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"Presentation\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type:application/xhtml+xml\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", start] dataUsingEncoding:NSUTF8StringEncoding]];

for (int i=0; i< self.selectedImages.count; i++) {

    self.imgObject = (ImageObjects *)[self.selectedImages objectAtIndex:i];

    FileModel *fileModel = [FileModel new];
    fileModel.fileData = self.imgObject.image_data;
    fileModel.fileName =  self.imgObject.imageName;
    fileModel.fileType = FileTypeImage;

    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\" \r\n",[selecedFileNames objectAtIndex:i]] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"\r\n--" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:fileModel.fileData]];
    [body appendData:[@"--\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

}

[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n.", boundary] dataUsingEncoding:NSUTF8StringEncoding]];


NSString *finalBody =[[NSString alloc] initWithData:body encoding:NSASCIIStringEncoding];

// set request body
[request setHTTPBody:body];

if (self.client)
{
    // Send the HTTP request.
    [self sendRequest:request];
}

I am successfully able to create page with images in OneNote but i am unable to see images on page. Please help me on this. Unable to find out what is the problem in request. Is there any problem is request i am creating ?

Vijay Kachhadiya
  • 366
  • 2
  • 11
  • This is only the sample code provided my Microsoft. Can you share your specific code? Where do the images come from? Are you sending the image in the requests as a multipart, or are you referencing the image URL in the HTML like ? – Jorge Aguirre Jan 30 '17 at 17:02

2 Answers2

2

If you're getting a "413" response code, then that means you're exceeding the size of the request you're sending to the API. It depends on the total size of the images you are sending, not the number of images.

Note that sending images via a Base64 string causes a 33% increase in its size (that is what the sample is doing). You can avoid this 33% hit by sending a multipart request. Additionally you can significantly reduce your image size by using a file format like JPEG (looks like you're using PNG, so you might have to still take extra steps to reduce the image size).

Our iOS sample does exactly this in the function createPageWithImage

NSString *attachmentPartName = @"pngattachment1";
NSString *date = dateInISO8601Format();
UIImage *logo = [UIImage imageNamed:@"Logo"];

NSString *simpleHtml = [NSString stringWithFormat:
                        @"<html>"
                        "<head>"
                        "<title>A simple page with an image from iOS</title>"
                        "<meta name=\"created\" content=\"%@\" />"
                        "</head>"
                        "<body>"
                        "<h1>This is a page with an image on it</h1>"
                        "<img src=\"name:%@\" alt=\"A beautiful logo\" width=\"%.0f\" height=\"%.0f\" />"
                        "</body>"
                        "</html>", date, attachmentPartName, [logo size].width, [logo size].height];

NSData *presentation = [simpleHtml dataUsingEncoding:NSUTF8StringEncoding];
NSData *image1 = UIImageJPEGRepresentation(logo, 1.0);
NSString *endpointToRequest = [ONSCPSCreateExamples getPagesEndpointUrlWithSectionName:sectionName];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:endpointToRequest parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
    [formData
     appendPartWithHeaders:@{
                             @"Content-Disposition" : @"form-data; name=\"Presentation\"",
                             @"Content-Type" : @"text/html"}
     body:presentation];
    [formData
     appendPartWithHeaders:@{
                             @"Content-Disposition" : [NSString stringWithFormat:@"form-data; name=\"%@\"", attachmentPartName],
                             @"Content-Type" : @"image/jpeg"}
     body:image1];
}];

If you have these headers:

Content-Type: multipart/form-data; boundary=0FA204EB-20EA-4E56-99EC-5EF56D600E02

And this body, it should work.

--0FA204EB-20EA-4E56-99EC-5EF56D600E02
Content-Disposition: form-data; name="Presentation"
Content-Type: text/html
<!DOCTYPE html>
<html><head><title>Created By Photo</title>
<meta name="created" content="2017-02-01T11:34:11+05:30" /></head><body><p>This is some <b>Photo</b> <i>Created</i> note.</p></body><h1>This is a note with image.</h1>
<img src="name:2017-02-01060411+0000.JPG" alt="image" ></body></html>
--0FA204EB-20EA-4E56-99EC-5EF56D600E02
Content-Disposition: form-data; name="2017-02-01060411+0000.JPG"
Content-Type: image/jpeg
IMAGE
--0FA204EB-20EA-4E56-99EC-5EF56D600E02--
.
Jorge Aguirre
  • 2,787
  • 3
  • 20
  • 27
  • please have a look i updated my question. And the images i have stored in my document directory and i am convert it into data. – Vijay Kachhadiya Jan 30 '17 at 17:12
  • Got it. Updated my answer. – Jorge Aguirre Jan 30 '17 at 17:26
  • where i can get this AFHTTPRequestSerializer. I just installed OneDrive sdk as suggested in site The Live SDK has been replaced by the OneDrive API. – Vijay Kachhadiya Jan 30 '17 at 17:44
  • Check out the sample Readme.md file. It has all you need. https://github.com/OneNoteDev/OneNoteAPISampleiOS – Jorge Aguirre Jan 30 '17 at 19:20
  • Also, you don't strictly need it - you just have to issue a multipart request. This is a very common thing - see http://stackoverflow.com/questions/24250475/post-multipart-form-data-with-objective-c – Jorge Aguirre Jan 30 '17 at 19:21
  • i updated my question and created a multipart request. But dont know i am unable to get where is the issue in my request. Please help me on this – Vijay Kachhadiya Jan 31 '17 at 10:53
  • Getting the whole output of your body (the value of the [NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding] right before it is appended to the body) would be useful. You can check out how the POST pages ApiGee sample builds the multipart request and compare that. https://apigee.com/onenote/embed/console/onenote/ – Jorge Aguirre Jan 31 '17 at 18:32
  • Also, our iOS REST API explorer has an example that builds a multipart in iOS differently - you might find that useful. https://github.com/OneNoteDev/iOS-REST-API-Explorer/blob/6b5bb9e45c8b3b4177d8e496c60f324852b2fb73/iOS-REST-API-Explorer/OneNoteManager.m#L250 – Jorge Aguirre Jan 31 '17 at 18:32
  • i attached my body part please have a look and let me know where is the issue i am unable to find out. – Vijay Kachhadiya Feb 01 '17 at 06:33
  • --0FA204EB-20EA-4E56-99EC-5EF56D600E02 Content-Disposition: form-data; name="Presentation" Content-Type: text/html Created By Photo

    This is some Photo Created note.

    YOUR BODYimage

    --0FA204EB-20EA-4E56-99EC-5EF56D600E02 Content-Disposition: form-data; name="2017-02-01060411+0000.JPG" Content-Type: image/jpeg IMAGE --0FA204EB-20EA-4E56-99EC-5EF56D600E02-- .

    – Jorge Aguirre Feb 01 '17 at 08:15
  • This payload is valid. Updating my answer. – Jorge Aguirre Feb 01 '17 at 08:15
  • I am doing same. I just pasted this payload in body and send request but getting The multi-part payload was malformed. Please can you provide me screenshot of that. – Vijay Kachhadiya Feb 01 '17 at 09:28
  • can you please provide me any demo like the way i am trying to do all this stuff by programmatically.If it is possible then it will be very helpful for me. – Vijay Kachhadiya Feb 01 '17 at 18:40
  • The ApiGee console has a demo for POST ~/pages. – Jorge Aguirre Feb 01 '17 at 18:42
  • Now i am successfully able to create note. But only one thing is i am unable to see image on my created note. Also when i pass image data, i am getting error The multi-part payload was malformed. So i convert image data into base64 string and pass to request. So when i passed image by converting into base64 string then my note created but i cant see full image on note. Please any suggestion on how should be my body part when i am attach image with note ? – Vijay Kachhadiya Feb 02 '17 at 07:40
  • [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"%@\"\r\n",self.filePath] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Type:application/octet-stream\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // [body appendData:[NSData dataWithData:image1]]; [body appendData:[[NSString stringWithFormat:@"%@\r\n", imageString] dataUsingEncoding:NSUTF8StringEncoding]]; please have a look – Vijay Kachhadiya Feb 02 '17 at 07:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/134665/discussion-between-vijay-kachhadiya-and-jorge-aguirre). – Vijay Kachhadiya Feb 02 '17 at 09:44
  • Now last one things is when i opening webURL(url of created note) in app then in iPhone it is not opening but in iPAD it is opening. Is there any reason behind this? – Vijay Kachhadiya Feb 10 '17 at 05:19
  • why you are unresponsive on this question i asked ? Anything is wrong regarding question i asked ? Please let me know. – Vijay Kachhadiya Feb 11 '17 at 04:23
  • Sorry about the delays - I would recommend asking the URL question in another StackOverflow question. It is hard to track in this conversation. To give you a few pointers, if what you want is to open the OneNote application, you should be using the clientUrl, not the webUrl. – Jorge Aguirre Feb 11 '17 at 16:19
  • http://stackoverflow.com/questions/42197249/unable-to-open-onenote-weburl-in-iphone please have a look on this. – Vijay Kachhadiya Feb 13 '17 at 05:33
0

This is the for one or more images in note.

 NSMutableArray *selecedFileNames = [[NSMutableArray alloc] init];
 NSString *date = [self formatDate];

 NSString *pagesEndpoint = [NSString stringWithFormat:@"sections/%@/pages", selectedSectionId];
 NSString *fullEndpoint = [serviceRootUrl stringByAppendingString:pagesEndpoint];

NSString *start = [NSString stringWithFormat:@"<html>"
                   "<head>"
                   "<title>Created By Photo</title>"
                   "<meta name=\"created\" content=\"%@\" />"
                   "</head>"
                   "<body>"
                   "<h1>This is a page with an image on it</h1>",date];

for (int i = 0; i<self.selectedImages.count; i++) {

FileModel *fileModel = [FileModel new];
fileModel.fileData = self.imgObject.image_data;
fileModel.fileName =  self.imgObject.imageName;
fileModel.fileType = FileTypeImage;

 self.filePath = fileModel.getFileName;
 UIImage *img = [UIImage imageWithData:fileModel.fileData];
 NSString *trimmedString = [self.filePath  stringByReplacingOccurrencesOfString:@" " withString:[NSString stringWithFormat:@"%d",i]];
 self.filePath = [trimmedString  stringByReplacingOccurrencesOfString:@":" withString:@""];

 NSString *middle = [NSString stringWithFormat:@"<h1>This is image</h1>"
                     "<img src=\"name:%@\" alt=\"A beautiful image\" width=\"%.0f\" height=\"%.0f\" />\r\n",self.filePath,[img size].width, [img size].height];

 [selecedFileNames addObject:self.filePath];
 start = [start stringByAppendingString:middle];

 }

 start = [start stringByAppendingString:@"</body>\r\n"
 "</html>\r\n"];


 NSData *presentation = [start dataUsingEncoding:NSUTF8StringEncoding];

 NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:fullEndpoint parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {


  [formData appendPartWithHeaders:@{
                              @"Content-Disposition" : @"form-data;               name=\"Presentation\"",
                              @"Content-Type" : @"text/html"}
      body:presentation];


 for (int i=0; i< self.selectedImages.count; i++) {

 self.imgObject = (ImageObjects *)[self.selectedImages objectAtIndex:i];

 FileModel *fileModel = [FileModel new];
 fileModel.fileData = self.imgObject.image_data;
 fileModel.fileName =  self.imgObject.imageName;
 fileModel.fileType = FileTypeImage;


     [formData
      appendPartWithHeaders:@{
                              @"Content-Disposition" : [NSString stringWithFormat:@"form-data; name=\"%@\"", [selecedFileNames objectAtIndex:i]],
                              @"Content-Type" : @"image/jpeg"}
      body:fileModel.fileData];

 }

 } error:nil];

 if (self.client)
 {
 // Send the HTTP request.
 [self sendRequest:request];
 }
Vijay Kachhadiya
  • 366
  • 2
  • 11