仅在 Swift 4.2 中上传带有多部分表单数据的图像

2023-11-21

我尝试了很多解决方案。我得到了一些,但他们正在使用objective c code在某处。我只需要解决方案swift 4.2并且没有任何第三方(例如Alamofire)。使用它工作正常objective c类。

我已经能够仅使用标头和其他参数以及图像发出 POST 请求,如下所示:

使用分段请求上传文件 - Swift 4

如何使用 Swift 进行多部分/表单数据发布请求?

多部分表单(图像、参数、标题)快速使用 Alamofire 发布请求

在 Swift 中上传带有多部分表单数据的图像 iOS

如何使用 Swift 将图像上传到 iOS 中的服务器?


func sendFile(
    urlPath:String,
    fileName:String,
    data:NSData,
    completionHandler: (NSURLResponse!, NSData!, NSError!) -> Void){

        var url: NSURL = NSURL(string: urlPath)!
        var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)

        request1.HTTPMethod = "POST"

        let boundary = generateBoundary()
        let fullData = photoDataToFormData(data,boundary:boundary,fileName:fileName)

        request1.setValue("multipart/form-data; boundary=" + boundary,
            forHTTPHeaderField: "Content-Type")

        // REQUIRED!
        request1.setValue(String(fullData.length), forHTTPHeaderField: "Content-Length")

        request1.HTTPBody = fullData
        request1.HTTPShouldHandleCookies = false

        let queue:NSOperationQueue = NSOperationQueue()

        NSURLConnection.sendAsynchronousRequest(
            request1,
            queue: queue,
            completionHandler:completionHandler)
}

// this is a very verbose version of that function
// you can shorten it, but i left it as-is for clarity
// and as an example
func photoDataToFormData(data:NSData,boundary:String,fileName:String) -> NSData {
    var fullData = NSMutableData()

    // 1 - Boundary should start with --
    let lineOne = "--" + boundary + "\r\n"
    fullData.appendData(lineOne.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)

    // 2
    let lineTwo = "Content-Disposition: form-data; name=\"image\"; filename=\"" + fileName + "\"\r\n"
    NSLog(lineTwo)
    fullData.appendData(lineTwo.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)

    // 3
    let lineThree = "Content-Type: image/jpg\r\n\r\n"
    fullData.appendData(lineThree.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)

    // 4
    fullData.appendData(data)

    // 5
    let lineFive = "\r\n"
    fullData.appendData(lineFive.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)

    // 6 - The end. Notice -- at the start and at the end
    let lineSix = "--" + boundary + "--\r\n"
    fullData.appendData(lineSix.dataUsingEncoding(
        NSUTF8StringEncoding,
        allowLossyConversion: false)!)

    return fullData
} 


请检查我的解决方案,它采用了参数和图像。我已经使用 PHP、.net、java 进行了测试。

class func request(withImages path:APIMethods, method:URLMethod, token : String?, headers:[String:String]?, parameters: [String:Any]?,imageNames : [String], images:[Data], completion: @escaping(Any?, Error?, Bool)->Void) {


    if !Reachability.isConnectedToNetwork() {
        DispatchQueue.main.async {
            showAlert(message: AppMessages.connectionFailed.rawValue)
        }
        dissmissHud()
        return
    }

    var stringUrl = "\(APIManager.url)\(APIMethods.preFix.rawValue)\(path.rawValue)"
    if method == .get, let lastPath = parameters?.values.first as? String {
        stringUrl += lastPath
    }else{
        stringUrl += token ?? ""
    }


    // generate boundary string using a unique per-app string
    let boundary = UUID().uuidString

    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    print("\n\ncomplete Url :-------------- ",stringUrl," \n\n-------------: complete Url")
    guard let url = URL(string: stringUrl) else { return }
    var request = URLRequest(url: url)
    request.httpMethod = method.rawValue

    if headers != nil{
        print("\n\nHeaders :-------------- ",headers as Any,"\n\n --------------: Headers")
        for (key, value) in headers! {
            request.setValue(value, forHTTPHeaderField: key)

        }
    }

    // Set Content-Type Header to multipart/form-data, this is equivalent to submitting form data with file upload in a web browser
    // And the boundary is also set here
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    var data = Data()
    if parameters != nil{
        for(key, value) in parameters!{
            // Add the reqtype field and its value to the raw http request data
            data.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
            data.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!)
            data.append("\(value)".data(using: .utf8)!)
        }
    }
    for (index,imageData) in images.enumerated() {
        // Add the image data to the raw http request data
        data.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
        data.append("Content-Disposition: form-data; name=\"\(imageNames[index])\"; filename=\"\(imageNames[index])\"\r\n".data(using: .utf8)!)
        data.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
        data.append(imageData)
    }

    // End the raw http request data, note that there is 2 extra dash ("-") at the end, this is to indicate the end of the data
    data.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)

    // Send a POST request to the URL, with the data we created earlier
    session.uploadTask(with: request, from: data, completionHandler: { data, response, error in

        if let checkResponse = response as? HTTPURLResponse{
            if checkResponse.statusCode == 200{
                guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: [JSONSerialization.ReadingOptions.allowFragments]) else {
                    completion(nil, error, false)
                    return
                }
                let jsonString = String(data: data, encoding: .utf8)!
                print("\n\n---------------------------\n\n"+jsonString+"\n\n---------------------------\n\n")
                print(json)
                completion(json, nil, true)
            }else{
                guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) else {
                    completion(nil, error, false)
                    return
                }
                let jsonString = String(data: data, encoding: .utf8)!
                print("\n\n---------------------------\n\n"+jsonString+"\n\n---------------------------\n\n")
                print(json)
                completion(json, nil, false)
            }
        }else{
            guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) else {
                completion(nil, error, false)
                return
            }
            completion(json, nil, false)
        }

    }).resume()

}

extension Data {

    /// Append string to Data
    ///
    /// Rather than littering my code with calls to `data(using: .utf8)` to convert `String` values to `Data`, this wraps it in a nice convenient little extension to Data. This defaults to converting using UTF-8.
    ///
    /// - parameter string:       The string to be added to the `Data`.

    mutating func append(_ string: String, using encoding: String.Encoding = .utf8) {
        if let data = string.data(using: encoding) {
            append(data)
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仅在 Swift 4.2 中上传带有多部分表单数据的图像 的相关文章

  • iOS swift 应用程序启动时出现黑屏

    我有个问题 当我启动我的应用程序时 会看到黑屏几秒钟 然后出现启动屏幕 我的启动画面不是默认的 我使用了视图控制器 因为我的启动画面有一个动画 我搜索了一个解决方案 我得到了这个 在我的闪屏加载 iPhone 之前出现黑屏 https st
  • 使用 FormData 上传 JavaScript Blob

    我在将 javascript 创建的 blob 上传到我的服务器时遇到问题 基本思想是用户上传图像 在 javascript 中我对图像进行居中裁剪并在传输之前对其进行下采样 图像处理工作正常 但上传本身无法正常工作 这是执行从 canva
  • Sprite Kit - 确定轻弹精灵的滑动手势矢量

    我有一个游戏 圆形物体从屏幕底部射出 我希望能够滑动它们以将它们朝我滑动的方向轻弹 我的问题是 我不知道如何计算滑动的矢量 方向 以便使圆形物体以适当的速度向正确的方向轻拂 我使用的静态矢量 5 5 需要通过滑动速度和滑动方向来计算 另外
  • 如何获取多点触摸 UITapGestureRecognizer 的多个位置

    我的视图中有一个 UITapGestureRecognizer 我可以使用下面的代码很好地获取其触摸的位置 现在 如果我将此识别器的触摸次数更改为 2 或更多 它仍然会为我提供一个位置 如何获得两次触摸的两个位置 tapGesture lo
  • 剪裁为形状的 SwiftUI 图像在上下文菜单中具有透明填充

    在我的 SwiftUI 应用程序中 我的资产目录中有一张宽高比为 1 1 的图像 在我的代码中 我有一个Image使用不同的宽高比查看 将图像裁剪为新尺寸 Image My Image resizable aspectRatio conte
  • CloudKit 获取当前用户的所有订阅

    我设法在 Apple CloudKit 中保存 更改和删除记录 我什至收到了与订阅相关的通知 但我不知道如何列出当前用户的所有订阅 到目前为止 这是我的代码 let operation CKFetchSubscriptionsOperati
  • 如何创建一个仅接收一次信号,然后自行取消订阅/释放的 ReactiveCocoa 订阅者?

    我目前正在注册一个属性信号的订阅者 如下所示 RACAble self test subscribeNext id x NSLog signal fired 默认功能是每次 self test 更改时都会触发 但我只想触发一次 然后取消订阅
  • ios 8 opengl es 1.1 已停产?

    我们即将在 iOS 应用商店上推出一款游戏 最近我们发现它无法在 iOS 8 上运行 游戏加载到黑屏 但其他一切似乎都可以运行 可以听到音乐 对触摸屏有反应 但显示屏上没有任何反应 我们的引擎相当旧并且使用 OpenGL ES 1 1 我现
  • 设置使用 iPhone 相机拍摄的图像的类型

    如果我们使用 iPhone 相机拍摄照片 图像将默认以 JPEG 格式保存 我想以其他格式 例如 PNG 保存捕获的图像 是否可以 当我们从应用程序调用 iPhone 相机时 是否可以通过代码执行此操作 我们可以设置捕获图片后必须保存的图像
  • iOS UITableViewCell需要按两次才能调用didSelectRowAtIndexPath

    我有一个 UITableView 有时需要您触摸它两次才能选择一个单元格 更多细节 仅当表格一直向上或一直向下滚动后才需要两次触摸 只需第二次触摸即可呼叫didSelectRowAtIndexPath 当表格以自然的 向上滚动位置 打开时
  • iOS7及以上版本中如何在接收器和扬声器之间切换音频输出?

    我有一个音频播放器 可以选择在接近传感器通知 1 时将音频输出从扬声器切换到接收器 耳机 无论是否连接耳机 以下是我执行此操作的代码 void switchAudioOutput NSString output AVAudioSession
  • 如何改进 iOS 中的 TWTweetComposeViewController 代码?

    我已经实现了以下代码来进行 Twitter 共享 在我的代码中 我尝试测试 iOS 5 如果这不起作用 我会回到使用 ShareKit 的 Twitter 代码进行共享的旧方式 我向同事展示了代码 他建议我的代码可能有缺陷 我需要做两件事
  • 应用程序在第二次运行 nsnull 计数的循环时崩溃

    我有一个循环 第一次运行正常 但第二次循环时我得到 NSNull count unrecognized selector sent to instance 0x3a094a70 Terminating app due to uncaught
  • 移动 Safari 中的文件上传和 EXIF

    正如这些问题中所指出的 在某些情况下 iOS 上上传的照片的地理位置和其他 EXIF 元数据会被删除 在 safari 中 https apple stackexchange com questions 326789 gps exif fr
  • 如何更改 UISwitch 关闭状态的默认颜色?

    我想更改 UISwitch 中 onTintColor 的颜色以表示关闭状态 切换位于表格视图中 并且以编程方式进行切换 settingsSwitch setBackgroundColor UIColor whiteColor settin
  • Xcode 不会在故事板中显示我的文本字段占位符文本

    当我在属性检查器中分配文本字段的占位符值时 它不会显示在故事板中 但是 当我运行应用程序的模拟器时 它就在那里 我缺少什么设置吗 我只想能够在编辑器中看到占位符文本 下面是 xcode 和模拟器之一的屏幕截图 我遇到了同样的问题 幸运的是我
  • ios 8 核心数据崩溃

    保存时 CoreData 发生崩溃 2014 09 16 09 51 58 273 My app 2678 105246 Terminating app due to uncaught exception NSInvalidArgument
  • 删除后台 moc 中的对象然后在主 moc 中刷新它会导致 NSFetchedResultsController 更新崩溃

    我遇到了一个NSObjectInaccessibleException我无法理解 Terminating app due to uncaught exception NSObjectInaccessibleException reason
  • 在 Swift 3 中单击和双击 UITableViewCell

    我在 TableView Cell 上有故事板 segue 我用它来在单元格单击中传输到另一个 VCdidSelectRowAt方法 现在我双击了TapGestureRecognizer处理手机上的点击问题 问题是 单击时 segue 正在
  • 在 Swift 中将 Int 转换为 UInt32

    我正在制作一个 Tcp 客户端 因此使用CFStreamCreatePairWithSocketToHost它期望第二个参数为 UInt32 这是我正在尝试做的事情的示例 func initNetwork IP String Port In

随机推荐

  • 当前页面的 UIPageControl 点大小[重复]

    这个问题在这里已经有答案了 我试图找出如何使所选页面的点比其他页面稍大 如下所示 Page 1 Page 2 我可以更改点的颜色 大小all点 背景等 但不适用于specific当前页面的点 如何仅更改当前页面的点大小 这可以是 Swift
  • 删除整个 PHP 类

    class foo 假设该类存在于我的代码中 然后我不再需要该类并希望将其删除 以便稍后我可以用新类替换它 是否可以从运行时删除整个类 不可以 您不能在运行时删除或大幅修改 PHP 类 或函数
  • 处理错误后跳过承诺链

    使用https github com kriskowal q图书馆 我想知道是否可以做这样的事情 Module A function moduleA exportedFunction return promiseReturningServi
  • 从 ActiveDirectory 检索用户帐户到期时间

    我正在尝试从帐户中检索到期日期 我试过了 DirectoryEntry user new DirectoryEntry iMem var AccountExpiration DateTime FromFileTime int user Pr
  • 为什么 Task 比 ValueTask 更快?

    我正在做一个基准测试Task
  • 在 ActionBarSherlock 中将标题重力设置为中心

    您好 我想为我的主要活动应用自定义背景布局 我找不到解决办法 有人可以给我一些建议吗 希望在操作栏中有一个简单的带有背景的 TextView 这可能吗 我设法删除图标并设置背景图像 但是如何将文本的重力设置为居中并更改字体呢 getSupp
  • 如何获得连续的触摸事件?

    我的类扩展了 View 我需要在其上获取连续的触摸事件 如果我使用 public boolean onTouchEvent MotionEvent me if me getAction MotionEvent ACTION DOWN myA
  • 如何将 json 加载到我的 angular.js ng-model 中?

    我有一个我认为可能是一个非常明显的问题 但我无法在任何地方找到答案 我只是想将一些 JSON 数据从我的服务器加载到客户端 现在 我正在使用 JQuery 通过 AJAX 调用加载它 代码如下 它位于 html 文件中 到目前为止它有效 但
  • WPF 工具包数据网格单元格文本换行

    我的 WPF 数据网格的列是固定宽度的 这意味着行中的长文本被截断 我怎样才能让文字换行 如果您使用的是 DataGridTextColumn 则需要定义 DataGridTextColumn ElementStyle 的样式
  • Reactjs - 如何将值从子组件传递到祖父组件?

    下面是在reactjs中将值从子组件传递到父组件的正确示例 App jsx import React from react class App extends React Component constructor props super
  • 如何访问其他程序内存中的结构?

    我知道如何在 C 中导入和使用读 写进程内存 我正在做游戏训练师 我需要 直接 访问转换为结构的其他进程内存 我可以使用 readprocessmemory 或 writeprocessmemory 但这需要很多时间来实现许多结构 C 中有
  • 在旧的 Borland C 中使用 Visual C++ DLL?

    我必须支持使用旧的 Borland 编译器 BC 5 用 C 编写的旧应用程序 不幸的是 我们使用的旧 TCP IP 库开始显示出它的年龄 并且在 Vista 和 Win7 机器上出现问题 我有一个可用于 MS Visual C 的新函数库
  • 如何提取ctree()终端节点的分裂规则

    我有一个包含 6 个分类变量的数据集 级别范围从 5 到 28 我已获得以下输出 ctree 派对包 有 17 个终端节点 我已关注 Galled 的输入ctree 如何获取每个终端节点的分裂条件列表 达到我想要的输出 但是 我在运行代码时
  • $resource `get` 函数如何在 AngularJS 中同步工作?

    我当时正在看thisAngularJS 教程描述了如何使用 Angular 资源连接 Twitter 视频教程 这是在示例控制器中设置的资源 scope twitter resource http twitter com action ac
  • 使用 PHP 获取 TrueType 中可用的字符

    如何获取 TrueType 字体中所有可用字符的列表 使用 PHP PHP 似乎没有任何可用的扩展directly with FreeType 处理 TrueType 字体的统治性开源库 您可能需要使用适当的库来使用另一种语言 例如Perl
  • ModuleNotFoundError:没有名为“django”的模块

    我正在尝试在线制作一个项目 但出现一个我无法解决的错误 我已经安装了 django 但服务器给我这个错误 Virtualenv 也处于活动状态 2017 09 25 20 10 27 471 2017 09 25 20 10 30 892
  • 无法将 ListBox.ObjectCollection 转换为(类型化)数组

    我想将项目转换为字符串数组或我用来填充 ListBox DataSource 的类型 该类型已覆盖 ToString 但我似乎无法将其转换 甚至无法转换为 String String a String ListBox1 Items Cont
  • Cognito 用户池触发器上的 AWS Lambda 错误

    我正在尝试将一条记录插入到 DynamoDB 中 调用 Cognito 用户池的 预注册 触发器 出于测试目的 Lambda 函数非常简单 但在 AWSCognito CognitoIdentityServiceProvider Cogni
  • 刚刚开始出现 AIR SQLite 错误 3182 发生磁盘 I/O 错误

    我们的软件有一个新的测试版 进行了一些更改 但不是围绕我们的数据库层 我们刚刚开始在服务器日志中报告错误 3128 似乎一旦发生 只要应用程序打开 它就会发生 代码中最明显的部分是我们通过 SQLite 每秒记录数据的部分 仅这个月我们的服
  • 仅在 Swift 4.2 中上传带有多部分表单数据的图像

    我尝试了很多解决方案 我得到了一些 但他们正在使用objective c code在某处 我只需要解决方案swift 4 2并且没有任何第三方 例如Alamofire 使用它工作正常objective c类 我已经能够仅使用标头和其他参数以