Home IOS Development Simple multipart file add for Swift

Simple multipart file add for Swift

0
Simple multipart file add for Swift

[ad_1]

I consider that you have already heard concerning the well-known multipart-data add method that everybody likes to add information and submit type information, but when not, hopefully this text will enable you to just a little bit to know this stuff higher.

Let’s begin with some idea. Don’t be concerned, it is only one hyperlink, concerning the multipart/form-data content material sort specification. To shortly summarize it first I might wish to inform you a couple of phrases about how the HTTP layer works. In a nutshell, you ship some information with some headers (give it some thought as a key-value person data object) to a given URL utilizing a technique and as a response you may get again a standing code, some headers and perhaps some form of response information too. 🥜

  • HTTP request = Technique + URL + Headers + Physique (request information)
  • HTTP response = Standing code + Headers + Physique (response information)

The request technique & URL is fairly easy, the attention-grabbing half is once you specify the Content material-Sort HTTP header, in our case the multipart/form-data;boundary="xxx" worth means, that we’ll ship a request physique utilizing a number of components and we’ll use the “xxx” boundary string as a separator between the components. Oh, by the way in which every half can have it is personal sort and title, we’ll use the Content material-Disposition: form-data; title="field1" line to let the server learn about these fields, earlier than we really ship the precise content material worth.

That is greater than sufficient idea for now, let me snow you ways we are able to implement all of this utilizing Swift 5. To begin with, we wish to have the ability to append string values to a Information object, so we’ll prolong Information sort with an ‘append string utilizing encoding’ technique:

import Basis

public extension Information {

    mutating func append(
        _ string: String,
        encoding: String.Encoding = .utf8
    ) {
        guard let information = string.information(utilizing: encoding) else {
            return
        }
        append(information)
    }
}

Subsequent, we want one thing that may assemble the HTTP multipart physique information, for this goal we’ll construct a MultipartRequest object. We are able to set the boundary after we init this object and we’ll append the components wanted to assemble the HTTP physique information.

The personal strategies will assist to assemble every part, we merely append string values to the personal information object that holds our information construction. The general public API solely consists of two add features that you should utilize to append a key-value based mostly type subject or a whole file utilizing its information. 👍

public struct MultipartRequest {
    
    public let boundary: String
    
    personal let separator: String = "rn"
    personal var information: Information

    public init(boundary: String = UUID().uuidString) {
        self.boundary = boundary
        self.information = .init()
    }
    
    personal mutating func appendBoundarySeparator() {
        information.append("--(boundary)(separator)")
    }
    
    personal mutating func appendSeparator() {
        information.append(separator)
    }

    personal func disposition(_ key: String) -> String {
        "Content material-Disposition: form-data; title="(key)""
    }

    public mutating func add(
        key: String,
        worth: String
    ) {
        appendBoundarySeparator()
        information.append(disposition(key) + separator)
        appendSeparator()
        information.append(worth + separator)
    }

    public mutating func add(
        key: String,
        fileName: String,
        fileMimeType: String,
        fileData: Information
    ) {
        appendBoundarySeparator()
        information.append(disposition(key) + "; filename="(fileName)"" + separator)
        information.append("Content material-Sort: (fileMimeType)" + separator + separator)
        information.append(fileData)
        appendSeparator()
    }

    public var httpContentTypeHeadeValue: String {
        "multipart/form-data; boundary=(boundary)"
    }

    public var httpBody: Information {
        var bodyData = information
        bodyData.append("--(boundary)--")
        return bodyData
    }
}

The final remaining two public variables are helpers to simply get again the HTTP associated content material sort header worth utilizing the correct boundary and the entire information object that it’s best to to ship to the server. Here is how one can assemble the HTTP URLRequest utilizing the multipart struct.

var multipart = MultipartRequest()
for subject in [
    "firstName": "John",
    "lastName": "Doe"
] {
    multipart.add(key: subject.key, worth: subject.worth)
}

multipart.add(
    key: "file",
    fileName: "pic.jpg",
    fileMimeType: "picture/png",
    fileData: "fake-image-data".information(utilizing: .utf8)!
)


let url = URL(string: "https://httpbin.org/put up")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue(multipart.httpContentTypeHeadeValue, forHTTPHeaderField: "Content material-Sort")
request.httpBody = multipart.httpBody


let (information, response) = strive await URLSession.shared.information(for: request)

print((response as! HTTPURLResponse).statusCode)
print(String(information: information, encoding: .utf8)!)

As you’ll be able to see it is comparatively easy, you simply add the shape fields and the information that you just need to add, and get again the HTTP associated values utilizing the helper API. I hope this text will enable you to to simulate type submissions utilizing multipart requests with out problem. 😊

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here