Ios 使用HTTP请求在服务器上保存PDF文件

Ios 使用HTTP请求在服务器上保存PDF文件,ios,swift,pdf,Ios,Swift,Pdf,我正在开发一款iPad应用程序。在这方面,我有一个任务,我已经成功地转换成PDF文件的图像 现在我需要通过HTTP请求在服务器端保存转换后的PDF文件 当我发送HTTP请求时,出现错误无法读取数据,因为它的格式不正确。 我哪里做错了 我的代码 // url path to php file let url = URL(string: "\(Config.path)/uploadAva.php")! // declare request to this file var

我正在开发一款iPad应用程序。在这方面,我有一个任务,我已经成功地转换成PDF文件的图像

现在我需要通过HTTP请求在服务器端保存转换后的PDF文件

当我发送HTTP请求时,出现错误无法读取数据,因为它的格式不正确。

我哪里做错了

我的代码

 // url path to php file
    let url = URL(string: "\(Config.path)/uploadAva.php")!

    // declare request to this file
    var request = URLRequest(url: url)

    // declare method of passign inf to this file
    request.httpMethod = "POST"

    // param to be sent in body of request
    let param = ["AppId":Config.AppID , "uuid":Config.uuid , "Id" : userID]

    // body
    let boundary = "Boundary-\(UUID().uuidString)"
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

        // ... body
    request.httpBody = createBody(param, filePathKey: "file", imageDataKey: pdfdata as Data, boundary: boundary)

    // launc session
    URLSession.shared.dataTask(with: request) { data, response, error in

        // get main queue to communicate back to user
        DispatchQueue.main.async(execute: {

            if error == nil {

                do {

                    let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
                    print(json)


                } catch {

                   //Here I get error as The data couldn’t be read because it isn’t in the correct format.

                }


            } else {

            }


        })

        }.resume()


 // custom body of HTTP request to upload pdf file
func createBody(_ parameters: [String: String]?, filePathKey: String?, imageDataKey: Data, boundary: String) -> Data {

    let body = NSMutableData()

  if parameters != nil {
        for (key, value) in parameters! {
            body.appendString("--\(boundary)\r\n")
            body.appendString("Content-Disposition: attachment; name=\"\(key)\"\r\n\r\n")
            body.appendString("\(value)\r\n")
        }
    }

    let filename = "ava.pdf"

    let mimetype = "application/pdf"

    body.appendString("--\(boundary)\r\n")
    body.appendString("Content-Type: application/pdf;name=\"ava10.pdf\"\r\n" )
    body.appendString("Content-Disposition:attachment;filename=\"ava10.pdf\"\r\n")

    body.append(imageDataKey)
    body.appendString("\r\n")

    body.appendString("--\(boundary)--\r\n")

    return body as Data

}

像往常一样进行连接和跟踪

我不理解您的逻辑,请您解释一下。
Please follow below flow:



////// FILE BINARY DATA

NSData *data = FILE DATA;


////This will contain properties for server requirement & file properties

    NSDictionary *dictionary = FILE_SERVER_ATTRIBUTE_DICT


////Create Boundary
    NSDate *dt = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
    NSInteger timestamp = [dt timeIntervalSince1970];

    NSString *HTTPRequestBodyBoundary = [NSString stringWithFormat:@"BOUNDARY-%ld-%@", (long)timestamp, [[NSProcessInfo processInfo] globallyUniqueString]]; // You could calculate a better boundary here.
    multipartBoundary = HTTPRequestBodyBoundary;


////HTTP BODY for request start

    NSMutableData *HTTPRequestBody = [NSMutableData data];

////Add Boundry to data : Opening Boundary
    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"--%@\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    // Add Key/Values to the Body
    NSEnumerator *enumerator = [dictionary keyEnumerator];
    NSString *key = nil;


//// Collecting HTTP Request body parts from File and server properties

    NSMutableArray *HTTPRequestBodyParts = [NSMutableArray array];

    while ((key = [enumerator nextObject]))
    {
        NSMutableData *someData = [[NSMutableData alloc] init];
        [someData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
        [someData appendData:[[NSString stringWithFormat:@"%@", [dictionary objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
        [HTTPRequestBodyParts addObject:someData];
    }

//// Adding boundaries for all components in collected Above array

    NSMutableData *resultingData = [NSMutableData data];
    NSUInteger count = [HTTPRequestBodyParts count];


    [HTTPRequestBodyParts enumerateObjectsUsingBlock:^(NSData *obj, NSUInteger idx, BOOL *stop) {
////Append data
        [resultingData appendData:obj];
        if (idx != count - 1)
        {
////Append Boundary to Data
            [resultingData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        }
    }];


////Add data to HTTP Body data
    [HTTPRequestBody appendData:resultingData];

////Append Boundary to Data HTTP Body data
    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

////Append FileName to HTTP Body data

    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n", @"uploadFile",request.fileNameWithExtension] dataUsingEncoding:NSUTF8StringEncoding]];

////Append Content Type to HTTP Body data

    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n",request.mimeTypeString] dataUsingEncoding:NSUTF8StringEncoding]];

////Append File Data to HTTP Body data

    [HTTPRequestBody appendData:data];   /// file data



////Append Boundary to Data HTTP Body data : Closing Boundary
    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];


//Above is ready for HTTP Body of URLRequest

    multipartData = HTTPRequestBody;

//// Create URLRequest 

    mutableResponseData = [NSMutableData new];
    webServiceURL = [SharedUtils trimString:webServiceURL];
    urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:webServiceURL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:httpTimeOut];

    [urlRequest setHTTPMethod:@"POST"];

    [urlRequest setHTTPBody:multipartData];
    [urlRequest addValue:[NSString stringWithFormat:@"%d", (int)[multipartData length]] forHTTPHeaderField:@"Content-Length"];
    [urlRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", multipartBoundary] forHTTPHeaderField:@"Content-Type"];


////  add auth header If applicable

 NSString *authStr = [NSString stringWithFormat:@"%@:%@", USERNAME, PASSWORD];
    NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
    NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]];
    [urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"];

    NSString *appVersion = [SharedUtils applicationVersionNumber];
    NSString *buildVersion = [SharedUtils applicationBuildNumber];
    [urlRequest setValue:[NSString stringWithFormat:@"%@-%@",[SharedUtils validateStringValue:appVersion], [SharedUtils validateStringValue:buildVersion]] forHTTPHeaderField:@"AppVersion"];
Please follow below flow:



////// FILE BINARY DATA

NSData *data = FILE DATA;


////This will contain properties for server requirement & file properties

    NSDictionary *dictionary = FILE_SERVER_ATTRIBUTE_DICT


////Create Boundary
    NSDate *dt = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
    NSInteger timestamp = [dt timeIntervalSince1970];

    NSString *HTTPRequestBodyBoundary = [NSString stringWithFormat:@"BOUNDARY-%ld-%@", (long)timestamp, [[NSProcessInfo processInfo] globallyUniqueString]]; // You could calculate a better boundary here.
    multipartBoundary = HTTPRequestBodyBoundary;


////HTTP BODY for request start

    NSMutableData *HTTPRequestBody = [NSMutableData data];

////Add Boundry to data : Opening Boundary
    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"--%@\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    // Add Key/Values to the Body
    NSEnumerator *enumerator = [dictionary keyEnumerator];
    NSString *key = nil;


//// Collecting HTTP Request body parts from File and server properties

    NSMutableArray *HTTPRequestBodyParts = [NSMutableArray array];

    while ((key = [enumerator nextObject]))
    {
        NSMutableData *someData = [[NSMutableData alloc] init];
        [someData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
        [someData appendData:[[NSString stringWithFormat:@"%@", [dictionary objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
        [HTTPRequestBodyParts addObject:someData];
    }

//// Adding boundaries for all components in collected Above array

    NSMutableData *resultingData = [NSMutableData data];
    NSUInteger count = [HTTPRequestBodyParts count];


    [HTTPRequestBodyParts enumerateObjectsUsingBlock:^(NSData *obj, NSUInteger idx, BOOL *stop) {
////Append data
        [resultingData appendData:obj];
        if (idx != count - 1)
        {
////Append Boundary to Data
            [resultingData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        }
    }];


////Add data to HTTP Body data
    [HTTPRequestBody appendData:resultingData];

////Append Boundary to Data HTTP Body data
    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

////Append FileName to HTTP Body data

    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n", @"uploadFile",request.fileNameWithExtension] dataUsingEncoding:NSUTF8StringEncoding]];

////Append Content Type to HTTP Body data

    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n",request.mimeTypeString] dataUsingEncoding:NSUTF8StringEncoding]];

////Append File Data to HTTP Body data

    [HTTPRequestBody appendData:data];   /// file data



////Append Boundary to Data HTTP Body data : Closing Boundary
    [HTTPRequestBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", HTTPRequestBodyBoundary] dataUsingEncoding:NSUTF8StringEncoding]];


//Above is ready for HTTP Body of URLRequest

    multipartData = HTTPRequestBody;

//// Create URLRequest 

    mutableResponseData = [NSMutableData new];
    webServiceURL = [SharedUtils trimString:webServiceURL];
    urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:webServiceURL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:httpTimeOut];

    [urlRequest setHTTPMethod:@"POST"];

    [urlRequest setHTTPBody:multipartData];
    [urlRequest addValue:[NSString stringWithFormat:@"%d", (int)[multipartData length]] forHTTPHeaderField:@"Content-Length"];
    [urlRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", multipartBoundary] forHTTPHeaderField:@"Content-Type"];


////  add auth header If applicable

 NSString *authStr = [NSString stringWithFormat:@"%@:%@", USERNAME, PASSWORD];
    NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
    NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]];
    [urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"];

    NSString *appVersion = [SharedUtils applicationVersionNumber];
    NSString *buildVersion = [SharedUtils applicationBuildNumber];
    [urlRequest setValue:[NSString stringWithFormat:@"%@-%@",[SharedUtils validateStringValue:appVersion], [SharedUtils validateStringValue:buildVersion]] forHTTPHeaderField:@"AppVersion"];