我想使用一种uploadTaskWithRequest
方法在后台上传多张图像。在尝试以下代码返回时,后台会话不支持从NSData上载任务…请如何实现此目的
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();
}
要在后台会话中上载,必须首先将数据保存到文件中。
HTTPBody
否则上传将失败。您可能还需要处理在后台运行应用程序时完成的html" target="_blank">上传。
为了使其更易于管理,请NSURLSession
为每个上传任务创建一个,每个任务都有一个唯一的标识符。
有关实现的详细信息,请参阅《URL会话编程指南》。
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.
}
}
要在单个请求中上载多个图像,必须先将图像编码为multipart / formdata
MIME类型,就像您所做的一样。区别在于,整个MIME消息必须保存到一个文件中,该文件是上载到服务器的文件。
这是显示此方法的示例。它通过将MIME部分直接序列化到文件来工作。您也可以在NSData中构建消息,尽管在处理大文件时可能会遇到内存限制。
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)
}
问题内容: 我是在项目中使用代码点火器的新用户,上载多个文件时遇到一个问题,但最后一个仅插入到所有图像“三个图像”字段中。 我的控制器是: 我的观点是: 请帮助如何插入3张图像。 我的资料库 问题答案: HTML: PHP的:
问题内容: 我使用,并将一些图像加载到上。 现在,我需要一次上传所有这些图像。正在使用,我该怎么做? 我浏览了文档,有一个名为的部分。但是,我无法上传中的图像。 *注意:我想以Byte Array 的形式上传图像。我怎样才能做到这一点?* 我到目前为止的代码, 问题答案: 试试这个。
问题内容: 我正在使用以下代码将单个图像上传到服务器: 如何通过编辑此代码在单个参数中上传多张图片? 问题答案: Swift 3 只需在图像上传参数中使用“ []”即可使其成为图像数组。
问题内容: 我在Swift iOS项目中使用Google Firebase。我的应用程序有一部分,用户从设备中选择多张照片进行上传。我正在尝试找到最佳实践,以将他们一次选择的所有照片上传到Firebase Storage。我知道如何上传一张照片。 我浏览了文档,没有看到有关上载多个NSData对象的任何方法,所以我只需要运行for循环并分别上载每个图像? 谢谢!感谢所有反馈。 问题答案: @Fra
问题内容: 我也曾在SO和其他教程中发表过很多文章,但是我没有得到任何最新的官方或其他文章,这些文章不包含使用Volley上传多个图像的弃用代码。我知道Apache HTTP Client删除并在新的android M中相关,因此建议改用下面的方法。 那么,有谁能帮我完成新的不推荐使用的少排球类上载多张图片的工作? 问题答案: 您可以从此处使用volley的最新版本。这是一个非官方的镜像,带有一些
我在SO和其他tuts中看了很多帖子,但我无法得到任何最新的官方或其他帖子,其中不包含任何关于使用排球上传多个图片的不推荐代码。我了解了Apache HTTP客户端删除和新android M中的相关内容,所以更喜欢使用下面的内容。