From e3a78da4bb766d2e59c0be670a69d9f43aadaf3f Mon Sep 17 00:00:00 2001
From: zunda <47569369+zunda-pixel@users.noreply.github.com>
Date: Sat, 13 Apr 2024 03:17:18 +0900
Subject: [PATCH] Support timeout in Swift (#229)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

## 🧰 Changes

- support `timeout` paramater
- remove `final newline`
- remove `FoundationNetworking`
- remove extra code in `multipart/form-data`

## 🧬 QA & Testing

I fixed test code in
`/httpsnippet/src/targets/swift/urlsession/fixtures/`

`npm run test`
---
 src/targets/swift/urlsession/client.ts        | 77 ++++++++-----------
 .../fixtures/application-form-encoded.swift   | 18 ++---
 .../fixtures/application-json.swift           |  9 +--
 .../swift/urlsession/fixtures/cookies.swift   | 10 +--
 .../urlsession/fixtures/custom-method.swift   |  6 +-
 .../swift/urlsession/fixtures/full.swift      | 22 +++---
 .../swift/urlsession/fixtures/headers.swift   | 16 ++--
 .../urlsession/fixtures/http-insecure.swift   |  6 +-
 .../urlsession/fixtures/indent-option.swift   |  6 +-
 .../urlsession/fixtures/json-null-value.swift |  9 +--
 .../fixtures/jsonObj-multiline.swift          |  9 +--
 .../fixtures/jsonObj-null-value.swift         |  9 +--
 .../urlsession/fixtures/multipart-data.swift  | 17 ++--
 .../urlsession/fixtures/multipart-file.swift  | 17 ++--
 .../multipart-form-data-no-params.swift       | 10 +--
 .../fixtures/multipart-form-data.swift        | 17 ++--
 .../swift/urlsession/fixtures/nested.swift    |  6 +-
 .../fixtures/postdata-malformed.swift         | 10 +--
 .../urlsession/fixtures/pretty-option.swift   | 14 ++--
 .../urlsession/fixtures/query-encoded.swift   |  6 +-
 .../swift/urlsession/fixtures/query.swift     |  6 +-
 .../swift/urlsession/fixtures/short.swift     |  6 +-
 .../urlsession/fixtures/text-plain.swift      | 10 +--
 .../urlsession/fixtures/timeout-option.swift  |  6 +-
 24 files changed, 120 insertions(+), 202 deletions(-)

diff --git a/src/targets/swift/urlsession/client.ts b/src/targets/swift/urlsession/client.ts
index 466f96b8..ec0b7c9a 100644
--- a/src/targets/swift/urlsession/client.ts
+++ b/src/targets/swift/urlsession/client.ts
@@ -10,7 +10,7 @@
 import type { Client } from '../../index.js';
 
 import { CodeBuilder } from '../../../helpers/code-builder.js';
-import { literalDeclaration } from '../helpers.js';
+import { literalRepresentation, literalDeclaration } from '../helpers.js';
 
 export interface UrlsessionOptions {
   pretty?: boolean;
@@ -29,47 +29,35 @@ export const urlsession: Client<UrlsessionOptions> = {
     const opts = {
       indent: '  ',
       pretty: true,
-      timeout: '10',
+      timeout: 10,
       ...options,
     };
 
     const { push, blank, join } = new CodeBuilder({ indent: opts.indent });
 
-    // Markers for headers to be created as litteral objects and later be set on the URLRequest if exist
-    const req = {
-      hasHeaders: false,
-      hasBody: false,
-    };
-
-    // We just want to make sure people understand that is the only dependency
     push('import Foundation');
-    push('#if canImport(FoundationNetworking)');
-    push('  import FoundationNetworking');
-    push('#endif');
-
-    if (Object.keys(allHeaders).length) {
-      req.hasHeaders = true;
-      blank();
-      push(literalDeclaration('headers', allHeaders, opts));
-    }
-
-    if (postData.text || postData.jsonObj || postData.params) {
-      req.hasBody = true;
+    blank();
 
+    const hasBody = postData.text || postData.jsonObj || postData.params;
+    if (hasBody) {
       switch (postData.mimeType) {
         case 'application/x-www-form-urlencoded':
           // By appending parameters one by one in the resulting snippet,
           // we make it easier for the user to edit it according to his or her needs after pasting.
           // The user can just add/remove lines adding/removing body parameters.
-          blank();
           if (postData.params?.length) {
-            const [head, ...tail] = postData.params;
-            push(`${tail.length > 0 ? 'var' : 'let'} postData = Data("${head.name}=${head.value}".utf8)`);
-            tail.forEach(({ name, value }) => {
-              push(`postData.append(Data("&${name}=${value}".utf8))`);
-            });
-          } else {
-            req.hasBody = false;
+            const parameters = postData.params.map(p => `"${p.name}": "${p.value}"`);
+            if (opts.pretty) {
+              push('let parameters = [');
+              parameters.forEach(param => push(`${param},`, 1));
+              push(']');
+            } else {
+              push(`let parameters = [${parameters.join(', ')}]`);
+            }
+
+            push('let joinedParameters = parameters.map { "\\($0.key)=\\($0.value)" }.joined(separator: "&")');
+            push('let postData = Data(joinedParameters.utf8)');
+            blank();
           }
           break;
 
@@ -77,8 +65,8 @@ export const urlsession: Client<UrlsessionOptions> = {
           if (postData.jsonObj) {
             push(`${literalDeclaration('parameters', postData.jsonObj, opts)} as [String : Any]`);
             blank();
-
             push('let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])');
+            blank();
           }
           break;
 
@@ -94,17 +82,13 @@ export const urlsession: Client<UrlsessionOptions> = {
           push(`let boundary = "${postData.boundary}"`);
           blank();
           push('var body = ""');
-          push('var error: NSError? = nil');
           push('for param in parameters {');
           push('let paramName = param["name"]!', 1);
           push('body += "--\\(boundary)\\r\\n"', 1);
           push('body += "Content-Disposition:form-data; name=\\"\\(paramName)\\""', 1);
           push('if let filename = param["fileName"] {', 1);
           push('let contentType = param["content-type"]!', 2);
-          push('let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)', 2);
-          push('if (error != nil) {', 2);
-          push('print(error as Any)', 3);
-          push('}', 2);
+          push('let fileContent = try String(contentsOfFile: filename, encoding: .utf8)', 2);
           push('body += "; filename=\\"\\(filename)\\"\\r\\n"', 2);
           push('body += "Content-Type: \\(contentType)\\r\\n\\r\\n"', 2);
           push('body += fileContent', 2);
@@ -112,16 +96,17 @@ export const urlsession: Client<UrlsessionOptions> = {
           push('body += "\\r\\n\\r\\n\\(paramValue)"', 2);
           push('}', 1);
           push('}');
+          blank();
+          push('let postData = Data(body.utf8)');
+          blank();
           break;
 
         default:
-          blank();
           push(`let postData = Data("${postData.text}".utf8)`);
+          blank();
       }
     }
 
-    blank();
-
     push(`let url = URL(string: "${uriObj.href}")!`);
 
     const queries = queryObj ? Object.entries(queryObj) : [];
@@ -136,11 +121,11 @@ export const urlsession: Client<UrlsessionOptions> = {
         const value = query[1];
         switch (Object.prototype.toString.call(value)) {
           case '[object String]':
-            push(`${opts.indent}URLQueryItem(name: "${key}", value: "${value}"),`);
+            push(`URLQueryItem(name: "${key}", value: "${value}"),`, 1);
             break;
           case '[object Array]':
-            value.forEach(val => {
-              push(`${opts.indent}URLQueryItem(name: "${key}", value: "${val}"),`);
+            (value as string[]).forEach((val: string) => {
+              push(`URLQueryItem(name: "${key}", value: "${val}"),`, 1);
             });
             break;
         }
@@ -153,23 +138,21 @@ export const urlsession: Client<UrlsessionOptions> = {
     }
 
     push(`request.httpMethod = "${method}"`);
+    push(`request.timeoutInterval = ${opts.timeout}`);
 
-    if (req.hasHeaders) {
-      push('request.allHTTPHeaderFields = headers');
+    if (Object.keys(allHeaders).length) {
+      push(`request.allHTTPHeaderFields = ${literalRepresentation(allHeaders, opts)}`);
     }
 
-    if (req.hasBody) {
+    if (hasBody) {
       push('request.httpBody = postData');
     }
 
     blank();
-    // Retrieving the shared session will be less verbose than creating a new one.
 
     push('let (data, response) = try await URLSession.shared.data(for: request)');
     push('print(String(decoding: data, as: UTF8.self))');
 
-    blank();
-
     return join();
   },
 };
diff --git a/src/targets/swift/urlsession/fixtures/application-form-encoded.swift b/src/targets/swift/urlsession/fixtures/application-form-encoded.swift
index 2e5a5630..96b417ce 100644
--- a/src/targets/swift/urlsession/fixtures/application-form-encoded.swift
+++ b/src/targets/swift/urlsession/fixtures/application-form-encoded.swift
@@ -1,18 +1,18 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["content-type": "application/x-www-form-urlencoded"]
-
-var postData = Data("foo=bar".utf8)
-postData.append(Data("&hello=world".utf8))
+let parameters = [
+  "foo": "bar",
+  "hello": "world",
+]
+let joinedParameters = parameters.map { "\($0.key)=\($0.value)" }.joined(separator: "&")
+let postData = Data(joinedParameters.utf8)
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "application/x-www-form-urlencoded"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/application-json.swift b/src/targets/swift/urlsession/fixtures/application-json.swift
index d2c6b3cc..40eebf95 100644
--- a/src/targets/swift/urlsession/fixtures/application-json.swift
+++ b/src/targets/swift/urlsession/fixtures/application-json.swift
@@ -1,9 +1,5 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["content-type": "application/json"]
 let parameters = [
   "number": 1,
   "string": "f\"oo",
@@ -18,8 +14,9 @@ let postData = try JSONSerialization.data(withJSONObject: parameters, options: [
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "application/json"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/cookies.swift b/src/targets/swift/urlsession/fixtures/cookies.swift
index dd0f7cdb..7ffaac8d 100644
--- a/src/targets/swift/urlsession/fixtures/cookies.swift
+++ b/src/targets/swift/urlsession/fixtures/cookies.swift
@@ -1,14 +1,10 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
-
-let headers = ["cookie": "foo=bar; bar=baz"]
 
 let url = URL(string: "https://httpbin.org/cookies")!
 var request = URLRequest(url: url)
 request.httpMethod = "GET"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["cookie": "foo=bar; bar=baz"]
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/custom-method.swift b/src/targets/swift/urlsession/fixtures/custom-method.swift
index 40b4a86f..ca11226f 100644
--- a/src/targets/swift/urlsession/fixtures/custom-method.swift
+++ b/src/targets/swift/urlsession/fixtures/custom-method.swift
@@ -1,11 +1,9 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "PROPFIND"
+request.timeoutInterval = 10
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/full.swift b/src/targets/swift/urlsession/fixtures/full.swift
index 7df94abd..51546cf0 100644
--- a/src/targets/swift/urlsession/fixtures/full.swift
+++ b/src/targets/swift/urlsession/fixtures/full.swift
@@ -1,15 +1,10 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = [
-  "cookie": "foo=bar; bar=baz",
-  "accept": "application/json",
-  "content-type": "application/x-www-form-urlencoded"
+let parameters = [
+  "foo": "bar",
 ]
-
-let postData = Data("foo=bar".utf8)
+let joinedParameters = parameters.map { "\($0.key)=\($0.value)" }.joined(separator: "&")
+let postData = Data(joinedParameters.utf8)
 
 let url = URL(string: "https://httpbin.org/anything?key=value")!
 var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
@@ -23,8 +18,13 @@ components.queryItems = components.queryItems.map { $0 + queryItems } ?? queryIt
 
 var request = URLRequest(url: components.url!)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = [
+  "cookie": "foo=bar; bar=baz",
+  "accept": "application/json",
+  "content-type": "application/x-www-form-urlencoded"
+]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/headers.swift b/src/targets/swift/urlsession/fixtures/headers.swift
index da999ee4..7bb9413b 100644
--- a/src/targets/swift/urlsession/fixtures/headers.swift
+++ b/src/targets/swift/urlsession/fixtures/headers.swift
@@ -1,19 +1,15 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = [
+let url = URL(string: "https://httpbin.org/headers")!
+var request = URLRequest(url: url)
+request.httpMethod = "GET"
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = [
   "accept": "application/json",
   "x-foo": "Bar",
   "x-bar": "Foo",
   "quoted-value": "\"quoted\" 'string'"
 ]
 
-let url = URL(string: "https://httpbin.org/headers")!
-var request = URLRequest(url: url)
-request.httpMethod = "GET"
-request.allHTTPHeaderFields = headers
-
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/http-insecure.swift b/src/targets/swift/urlsession/fixtures/http-insecure.swift
index e4826673..35f8cedc 100644
--- a/src/targets/swift/urlsession/fixtures/http-insecure.swift
+++ b/src/targets/swift/urlsession/fixtures/http-insecure.swift
@@ -1,11 +1,9 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "http://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "GET"
+request.timeoutInterval = 10
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/indent-option.swift b/src/targets/swift/urlsession/fixtures/indent-option.swift
index d7ae5274..57129ea4 100644
--- a/src/targets/swift/urlsession/fixtures/indent-option.swift
+++ b/src/targets/swift/urlsession/fixtures/indent-option.swift
@@ -1,11 +1,9 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "GET"
+request.timeoutInterval = 10
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/json-null-value.swift b/src/targets/swift/urlsession/fixtures/json-null-value.swift
index caac59fe..d34f232a 100644
--- a/src/targets/swift/urlsession/fixtures/json-null-value.swift
+++ b/src/targets/swift/urlsession/fixtures/json-null-value.swift
@@ -1,9 +1,5 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["content-type": "application/json"]
 let parameters = ["foo": nil] as [String : Any]
 
 let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])
@@ -11,8 +7,9 @@ let postData = try JSONSerialization.data(withJSONObject: parameters, options: [
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "application/json"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/jsonObj-multiline.swift b/src/targets/swift/urlsession/fixtures/jsonObj-multiline.swift
index ed53b1ef..34e3bf2c 100644
--- a/src/targets/swift/urlsession/fixtures/jsonObj-multiline.swift
+++ b/src/targets/swift/urlsession/fixtures/jsonObj-multiline.swift
@@ -1,9 +1,5 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["content-type": "application/json"]
 let parameters = ["foo": "bar"] as [String : Any]
 
 let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])
@@ -11,8 +7,9 @@ let postData = try JSONSerialization.data(withJSONObject: parameters, options: [
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "application/json"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/jsonObj-null-value.swift b/src/targets/swift/urlsession/fixtures/jsonObj-null-value.swift
index caac59fe..d34f232a 100644
--- a/src/targets/swift/urlsession/fixtures/jsonObj-null-value.swift
+++ b/src/targets/swift/urlsession/fixtures/jsonObj-null-value.swift
@@ -1,9 +1,5 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["content-type": "application/json"]
 let parameters = ["foo": nil] as [String : Any]
 
 let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])
@@ -11,8 +7,9 @@ let postData = try JSONSerialization.data(withJSONObject: parameters, options: [
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "application/json"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/multipart-data.swift b/src/targets/swift/urlsession/fixtures/multipart-data.swift
index 529bf799..56a45a88 100644
--- a/src/targets/swift/urlsession/fixtures/multipart-data.swift
+++ b/src/targets/swift/urlsession/fixtures/multipart-data.swift
@@ -1,9 +1,5 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["content-type": "multipart/form-data; boundary=---011000010111000001101001"]
 let parameters = [
   [
     "name": "foo",
@@ -20,17 +16,13 @@ let parameters = [
 let boundary = "---011000010111000001101001"
 
 var body = ""
-var error: NSError? = nil
 for param in parameters {
   let paramName = param["name"]!
   body += "--\(boundary)\r\n"
   body += "Content-Disposition:form-data; name=\"\(paramName)\""
   if let filename = param["fileName"] {
     let contentType = param["content-type"]!
-    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
-    if (error != nil) {
-      print(error as Any)
-    }
+    let fileContent = try String(contentsOfFile: filename, encoding: .utf8)
     body += "; filename=\"\(filename)\"\r\n"
     body += "Content-Type: \(contentType)\r\n\r\n"
     body += fileContent
@@ -39,11 +31,14 @@ for param in parameters {
   }
 }
 
+let postData = Data(body.utf8)
+
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "multipart/form-data; boundary=---011000010111000001101001"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/multipart-file.swift b/src/targets/swift/urlsession/fixtures/multipart-file.swift
index ba9c867d..19a5bbed 100644
--- a/src/targets/swift/urlsession/fixtures/multipart-file.swift
+++ b/src/targets/swift/urlsession/fixtures/multipart-file.swift
@@ -1,9 +1,5 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["content-type": "multipart/form-data; boundary=---011000010111000001101001"]
 let parameters = [
   [
     "name": "foo",
@@ -15,17 +11,13 @@ let parameters = [
 let boundary = "---011000010111000001101001"
 
 var body = ""
-var error: NSError? = nil
 for param in parameters {
   let paramName = param["name"]!
   body += "--\(boundary)\r\n"
   body += "Content-Disposition:form-data; name=\"\(paramName)\""
   if let filename = param["fileName"] {
     let contentType = param["content-type"]!
-    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
-    if (error != nil) {
-      print(error as Any)
-    }
+    let fileContent = try String(contentsOfFile: filename, encoding: .utf8)
     body += "; filename=\"\(filename)\"\r\n"
     body += "Content-Type: \(contentType)\r\n\r\n"
     body += fileContent
@@ -34,11 +26,14 @@ for param in parameters {
   }
 }
 
+let postData = Data(body.utf8)
+
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "multipart/form-data; boundary=---011000010111000001101001"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/multipart-form-data-no-params.swift b/src/targets/swift/urlsession/fixtures/multipart-form-data-no-params.swift
index eb2276ac..3e6dc16d 100644
--- a/src/targets/swift/urlsession/fixtures/multipart-form-data-no-params.swift
+++ b/src/targets/swift/urlsession/fixtures/multipart-form-data-no-params.swift
@@ -1,14 +1,10 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
-
-let headers = ["Content-Type": "multipart/form-data"]
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["Content-Type": "multipart/form-data"]
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/multipart-form-data.swift b/src/targets/swift/urlsession/fixtures/multipart-form-data.swift
index e9d349eb..ec50e6d8 100644
--- a/src/targets/swift/urlsession/fixtures/multipart-form-data.swift
+++ b/src/targets/swift/urlsession/fixtures/multipart-form-data.swift
@@ -1,9 +1,5 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["Content-Type": "multipart/form-data; boundary=---011000010111000001101001"]
 let parameters = [
   [
     "name": "foo",
@@ -14,17 +10,13 @@ let parameters = [
 let boundary = "---011000010111000001101001"
 
 var body = ""
-var error: NSError? = nil
 for param in parameters {
   let paramName = param["name"]!
   body += "--\(boundary)\r\n"
   body += "Content-Disposition:form-data; name=\"\(paramName)\""
   if let filename = param["fileName"] {
     let contentType = param["content-type"]!
-    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
-    if (error != nil) {
-      print(error as Any)
-    }
+    let fileContent = try String(contentsOfFile: filename, encoding: .utf8)
     body += "; filename=\"\(filename)\"\r\n"
     body += "Content-Type: \(contentType)\r\n\r\n"
     body += fileContent
@@ -33,11 +25,14 @@ for param in parameters {
   }
 }
 
+let postData = Data(body.utf8)
+
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["Content-Type": "multipart/form-data; boundary=---011000010111000001101001"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/nested.swift b/src/targets/swift/urlsession/fixtures/nested.swift
index a67a057b..f512fef8 100644
--- a/src/targets/swift/urlsession/fixtures/nested.swift
+++ b/src/targets/swift/urlsession/fixtures/nested.swift
@@ -1,7 +1,4 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "https://httpbin.org/anything")!
 var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
@@ -14,6 +11,7 @@ components.queryItems = components.queryItems.map { $0 + queryItems } ?? queryIt
 
 var request = URLRequest(url: components.url!)
 request.httpMethod = "GET"
+request.timeoutInterval = 10
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/postdata-malformed.swift b/src/targets/swift/urlsession/fixtures/postdata-malformed.swift
index 29df4fd8..d3e7ff6e 100644
--- a/src/targets/swift/urlsession/fixtures/postdata-malformed.swift
+++ b/src/targets/swift/urlsession/fixtures/postdata-malformed.swift
@@ -1,14 +1,10 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
-
-let headers = ["content-type": "application/json"]
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "application/json"]
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/pretty-option.swift b/src/targets/swift/urlsession/fixtures/pretty-option.swift
index 3da5fca5..fbf55067 100644
--- a/src/targets/swift/urlsession/fixtures/pretty-option.swift
+++ b/src/targets/swift/urlsession/fixtures/pretty-option.swift
@@ -1,11 +1,8 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
-let headers = ["cookie": "foo=bar; bar=baz", "accept": "application/json", "content-type": "application/x-www-form-urlencoded"]
-
-let postData = Data("foo=bar".utf8)
+let parameters = ["foo": "bar"]
+let joinedParameters = parameters.map { "\($0.key)=\($0.value)" }.joined(separator: "&")
+let postData = Data(joinedParameters.utf8)
 
 let url = URL(string: "https://httpbin.org/anything?key=value")!
 var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
@@ -19,8 +16,9 @@ components.queryItems = components.queryItems.map { $0 + queryItems } ?? queryIt
 
 var request = URLRequest(url: components.url!)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["cookie": "foo=bar; bar=baz", "accept": "application/json", "content-type": "application/x-www-form-urlencoded"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/query-encoded.swift b/src/targets/swift/urlsession/fixtures/query-encoded.swift
index a264a7d2..dc249497 100644
--- a/src/targets/swift/urlsession/fixtures/query-encoded.swift
+++ b/src/targets/swift/urlsession/fixtures/query-encoded.swift
@@ -1,7 +1,4 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "https://httpbin.org/anything")!
 var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
@@ -13,6 +10,7 @@ components.queryItems = components.queryItems.map { $0 + queryItems } ?? queryIt
 
 var request = URLRequest(url: components.url!)
 request.httpMethod = "GET"
+request.timeoutInterval = 10
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/query.swift b/src/targets/swift/urlsession/fixtures/query.swift
index 8e5f34f2..230b7ab0 100644
--- a/src/targets/swift/urlsession/fixtures/query.swift
+++ b/src/targets/swift/urlsession/fixtures/query.swift
@@ -1,7 +1,4 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "https://httpbin.org/anything?key=value")!
 var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
@@ -15,6 +12,7 @@ components.queryItems = components.queryItems.map { $0 + queryItems } ?? queryIt
 
 var request = URLRequest(url: components.url!)
 request.httpMethod = "GET"
+request.timeoutInterval = 10
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/short.swift b/src/targets/swift/urlsession/fixtures/short.swift
index d7ae5274..57129ea4 100644
--- a/src/targets/swift/urlsession/fixtures/short.swift
+++ b/src/targets/swift/urlsession/fixtures/short.swift
@@ -1,11 +1,9 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "GET"
+request.timeoutInterval = 10
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/text-plain.swift b/src/targets/swift/urlsession/fixtures/text-plain.swift
index 72583278..4a3fa9cf 100644
--- a/src/targets/swift/urlsession/fixtures/text-plain.swift
+++ b/src/targets/swift/urlsession/fixtures/text-plain.swift
@@ -1,17 +1,13 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
-
-let headers = ["content-type": "text/plain"]
 
 let postData = Data("Hello World".utf8)
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "POST"
-request.allHTTPHeaderFields = headers
+request.timeoutInterval = 10
+request.allHTTPHeaderFields = ["content-type": "text/plain"]
 request.httpBody = postData
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file
diff --git a/src/targets/swift/urlsession/fixtures/timeout-option.swift b/src/targets/swift/urlsession/fixtures/timeout-option.swift
index d7ae5274..110a85fe 100644
--- a/src/targets/swift/urlsession/fixtures/timeout-option.swift
+++ b/src/targets/swift/urlsession/fixtures/timeout-option.swift
@@ -1,11 +1,9 @@
 import Foundation
-#if canImport(FoundationNetworking)
-  import FoundationNetworking
-#endif
 
 let url = URL(string: "https://httpbin.org/anything")!
 var request = URLRequest(url: url)
 request.httpMethod = "GET"
+request.timeoutInterval = 5
 
 let (data, response) = try await URLSession.shared.data(for: request)
-print(String(decoding: data, as: UTF8.self))
+print(String(decoding: data, as: UTF8.self))
\ No newline at end of file