在 slack API 上上传文件中的“无效表单数据”

问题描述

我正在处理一个项目,我需要使用 slack 的 API 将文件上传到 slack 工作区中的频道。这就是我读取文件内容的方式:

func readFile(localFilePath: String) -> Data? {
        var contents: Data
        let url = URL(fileURLWithPath: localFilePath)
        
        do {
            contents = try Data(contentsOf: url)
        } catch {
            return nil
        }

        return contents
    }

然而,这就是我的懈怠:

enter image description here

我还尝试将文件作为 String 读取,如下所示:

contents = try String(contentsOf: url,encoding: .ascii)

这样 slack 似乎可以识别出它是 PDF,但它是空白的(见下图)。

enter image description here

如果我添加显式 Content-Type 标头并将其设置为 multipart/form-data;,我会收到 invalid_form_data 错误响应。

这是请求代码

let reqHeaders: HTTPHeaders = [
            "Authorization": "","Accept": "application/json","Content-Type": "multipart/form-data;",]
let params: [String:Any] = [
            "channels": channelSelections.joined(separator: ","),"content": fileData,"initial_comment": messageText,"filename": filename
        ]
        AF.request(url,method: .post,parameters: params,headers: reqHeaders).responseJSON { response in
            switch response.result {
            case .success:
                if let data = response.data {
                    do {
                        let json = try JSON(data: data)
                        if json["ok"].boolValue {
                            // some code
                        } else {
                            print("\n\n\n\(json)\n\n\n")
                        }
                    }
                    catch{
                        print("JSON Error")
                    }
                    
                }
            case let .failure(error):
                print(error)
            }
        }

读取文件并将其作为负载发送到 slack 的 API 的正确方法是什么?

解决方法

let params: [String:Any] = [
            "channels": channelSelections.joined(separator: ","),"initial_comment": messageText
        ]
    
 let headers: HTTPHeaders = [
    
                   "Content-type": "multipart/form-data"
               ]
    
               Alamofire.upload(multipartFormData: { (multipartFormData) in
                   for (key,value) in params {
                       multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!,withName: key as String)
                   }
    
               
                       multipartFormData.append(fileData,withName: filename,fileName: filename,mimeType: "application/pdf")
                   
    
               },to:url,headers: headers)
               { (result) in
                   switch result{
                   case .success(let upload,_,_):
                       upload.responseJSON { response in
                           let json : JSON = JSON(response.result.value)
                            print(json)
                           if let err = response.error{
                               onError?(err)
    
                               return
                           }
                           onCompletion?(json)
    
                       }
                   case .failure(let error):
                      //print("Error in upload: \(error.localizedDescription)")
                       onError?(error)
    
                   }
    
               }

因此,您应该使用多部分上传您的 pdf,而不是常规的发布请求。更新您的参数并创建多部分。