2016-07-13 8 views
7

मैं एक uploadTaskWithRequest विधि का उपयोग कर पृष्ठभूमि में एकाधिक छवियां अपलोड करना चाहता हूं। जबकि निम्न कोड की कोशिश कर देता है NSData से अपलोड कार्यों पृष्ठभूमि सत्र में समर्थित नहीं हैं ... कैसे प्राप्त करने के लिए कृपया इसपृष्ठभूमि एकल NSURL सत्र अपलोड का उपयोग कर एकाधिक छवियों को अपलोड करें TaskWithRequest

func createRequest (param : NSDictionary ,imagearray :NSMutableArray, strURL : String) -> NSURLRequest { 

    let boundary = generateBoundaryString() 

    let url = NSURL(string: strURL) 
    let request = NSMutableURLRequest(URL: url!) 

    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") 
    request.HTTPMethod = "POST" 
    request.HTTPBody = createBodyWithParameters(param, image_array:imagearray,boundary: boundary); 

    return request 
} 

    func createBodyWithParameters(parameters: NSDictionary,image_array:NSMutableArray,boundary: String) -> NSData { 
let body = NSMutableData()   
for (key, value) in parameters { 
     if(value is String || value is NSString){ 
      body.appendString("--\(boundary)\r\n") 
      body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n") 
      body.appendString("\(value)\r\n") 
     } 
    } 
    var i = 0; 
    for image in image_array { 
     let filename = "image\(i).jpg" 
     let data = UIImagePNGRepresentation(image as! UIImage); 
     let mimetype = "image/png" 
     body.appendString("--\(boundary)\r\n") 
     body.appendString("Content-Disposition: form-data; name=\"\(self.filePathKey)\"; filename=\"\(filename)\"\r\n") 
     body.appendString("Content-Type: \(mimetype)\r\n\r\n") 
     body.appendData(data!) 
     body.appendString("\r\n") 
     i += 1; 
    } 

    body.appendString("--\(boundary)--\r\n") 
    //  NSLog("data %@",NSString(data: body, encoding: NSUTF8StringEncoding)!); 
    return body 
} 

func postrequestwithformdata(requesturl:String,postparams:NSDictionary,postformadata:NSMutableArray,requestId:Int) 
{ 

    self.requestid = requestId; 
    let requestformdata = self.createRequest(postparams, imagearray: postformadata, strURL: requesturl); 
    let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(Contants.identifier) 
    let session: NSURLSession = NSURLSession(configuration:configuration, delegate: self, delegateQueue: NSOperationQueue.mainQueue()); 
    let task: NSURLSessionUploadTask = session.uploadTaskWithRequest(requestformdata, fromData: requestformdata.HTTPBody!); 
    task.resume(); 

} 

उत्तर

10

एक पृष्ठभूमि सत्र में अपलोड करने के लिए, डेटा पहले एक फ़ाइल को बचाया जाना चाहिए।

  1. writeToFile:options: का उपयोग कर फ़ाइल में डेटा को सहेजें।
  2. कार्य बनाने के लिए NSURLSession uploadTaskWithRequest:fromFile: पर कॉल करें। ध्यान दें कि अनुरोध में HTTPBody में डेटा नहीं होना चाहिए अन्यथा अपलोड विफल हो जाएगा।
  3. URLSession:didCompleteWithError: प्रतिनिधि विधि में पूरा होने को संभालें।

आप ऐप पृष्ठभूमि में होने पर अपलोड को पूरा करना भी चाह सकते हैं।

  1. AppDelegate में application:handleEventsForBackgroundURLSession:completionHandler लागू करें।
  2. प्रदत्त पहचानकर्ता के साथ एक NSURL सत्र बनाएं।
  3. एक सामान्य अपलोड अनुसार प्रतिनिधि तरीकों का जवाब
  4. कॉल URLSessionDidFinishEventsForBackgroundURLSession जब आप घटना संसाधन पूरा कर लिया है (जैसे URLSession:didCompleteWithError: में प्रतिक्रिया संभाल)।

इसे प्रबंधित करने में आसान बनाने के लिए, प्रति अपलोड कार्य NSURLSession बनाएं, प्रत्येक एक अद्वितीय पहचानकर्ता के साथ।

कार्यान्वयन विवरण के लिए URL Session Programming Guide का संदर्भ लें।

उदाहरण AppDelegate:

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate { 

    var window: UIWindow? 

    typealias CompletionHandler =() -> Void 

    var completionHandlers = [String: CompletionHandler]() 

    var sessions = [String: NSURLSession]() 


    func upload(request: NSURLRequest, data: NSData) 
    { 
     // Create a unique identifier for the session. 
     let sessionIdentifier = NSUUID().UUIDString 

     let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask).first! 
     let fileURL = directoryURL.URLByAppendingPathComponent(sessionIdentifier) 

     // Write data to cache file. 
     data.writeToURL(fileURL, atomically: true); 

     let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(sessionIdentifier) 

     let session: NSURLSession = NSURLSession(
      configuration:configuration, 
      delegate: self, 
      delegateQueue: NSOperationQueue.mainQueue() 
     ) 

     // Store the session, so that we don't recreate it if app resumes from suspend. 
     sessions[sessionIdentifier] = session 

     let task = session.uploadTaskWithRequest(request, fromFile: fileURL) 

     task.resume() 
    } 

    // Called when the app becomes active, if an upload completed while the app was in the background. 
    func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: CompletionHandler) { 

     let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(identifier) 

     if sessions[identifier] == nil { 

      let session = NSURLSession(
       configuration: configuration, 
       delegate: self, 
       delegateQueue: NSOperationQueue.mainQueue() 
      ) 

      sessions[identifier] = session 
     } 

     completionHandlers[identifier] = completionHandler 
    } 

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { 

     // Handle background session completion handlers. 
     if let identifier = session.configuration.identifier { 

      if let completionHandler = completionHandlers[identifier] { 
       completionHandler() 
       completionHandlers.removeValueForKey(identifier) 
      } 

      // Remove session 
      sessions.removeValueForKey(identifier) 
     } 

     // Upload completed. 
    } 
} 

एक अनुरोध में कई छवियों को अपलोड करने के लिए, छवियों पहले, बहुखण्डीय/formdata MIME प्रकार में एन्कोड किया जाना चाहिए के रूप में किया है। अंतर यह है कि यह संपूर्ण MIME संदेश एक फ़ाइल में सहेजा जाना चाहिए, जो कि सर्वर पर अपलोड की गई फ़ाइल है।

यहां एक उदाहरण है जो दिखाता है कि यह कैसे करें। यह एमआईएमई भागों को सीधे फाइल में क्रमबद्ध करके काम करता है। आप एनएसडीटा में संदेश भी बना सकते हैं, हालांकि बड़ी फ़ाइलों को संभालने के दौरान आपको स्मृति सीमाओं में चलने का जोखिम होता है।

func uploadImages(request: NSURLRequest, images: [UIImage]) { 

    let uuid = NSUUID().UUIDString 
    let boundary = String(count: 24, repeatedValue: "-" as Character) + uuid 

    // Open the file 
    let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask).first! 

    let fileURL = directoryURL.URLByAppendingPathComponent(uuid) 
    let filePath = fileURL.path! 

    NSFileManager.defaultManager().createFileAtPath(filePath, contents: nil, attributes: nil) 

    let file = NSFileHandle(forWritingAtPath: filePath)! 


    // Write each image to a MIME part. 
    let newline = "\r\n" 

    for (i, image) in images.enumerate() { 

     let partName = "image-\(i)" 
     let partFilename = "\(partName).png" 
     let partMimeType = "image/png" 
     let partData = UIImagePNGRepresentation(image) 

     // Write boundary header 
     var header = "" 
     header += "--\(boundary)" + newline 
     header += "Content-Disposition: form-data; name=\"\(partName)\"; filename=\"\(partFilename)\"" + newline 
     header += "Content-Type: \(partMimeType)" + newline 
     header += newline 

     let headerData = header.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) 

     print("") 
     print("Writing header #\(i)") 
     print(header) 

     print("Writing data") 
     print("\(partData!.length) Bytes") 

     // Write data 
     file.writeData(headerData!) 
     file.writeData(partData!) 
    } 

    // Write boundary footer 
    var footer = "" 
    footer += newline 
    footer += "--\(boundary)--" + newline 
    footer += newline 

    print("") 
    print("Writing footer") 
    print(footer) 

    let footerData = footer.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) 
    file.writeData(footerData!) 

    file.closeFile() 

    // Add the content type for the request to multipart. 
    let outputRequest = request.copy() as! NSMutableURLRequest 

    let contentType = "multipart/form-data; boundary=\(boundary)" 
    outputRequest.setValue(contentType, forHTTPHeaderField: "Content-Type") 


    // Start uploading files. 
    upload(outputRequest, fileURL: fileURL) 
} 
+0

लेकिन मेरे पास बहुत सारे छवि फॉर्म डेटा हैं, इसे कैसे संभालें? –

+0

आप जो भी करने का प्रयास कर रहे हैं उसे स्पष्ट करने के लिए कृपया अपना प्रश्न अपडेट करें। चूंकि वर्तमान में, आपका प्रश्न एकाधिक छवियों के बारे में कुछ भी नहीं बताता है। –

+0

[इस ट्यूटोरियल] पर एक नज़र डालें [http://www.kaleidosblog.com/how-to-upload-images-using-swift-2-send-multipart-post-request), जो दिखाता है कि एमआईएमई एन्कोडिंग का उपयोग कैसे करें एक ही अपलोड अनुरोध में एकाधिक छवियों को एन्कोड करने के लिए। –

संबंधित मुद्दे