Merge pull request #813 from badnikhil/add-feature-460

Add CodeGen for Swift (Alamofire)
This commit is contained in:
Ankit Mahato
2025-04-23 04:20:44 +05:30
committed by GitHub
5 changed files with 1283 additions and 3 deletions

View File

@ -29,7 +29,8 @@ Choose your programming language/library from the list provided below to learn m
- [Rust (reqwest)](#rust-reqwest)
- [Rust (ureq)](#rust-ureq)
- [Rust (Actix Client)](#rust-actix-client)
- [Swift](#swift)
- [Swift (URLSession)](#swift-urlsession)
- [Swift (Alamofire)](#swift-alamofire)
**Please raise a GitHub issue in case any instruction is not clear or if it is not working.**
@ -1073,6 +1074,133 @@ cargo run
TODO
## Swift
## Swift (URLSession)
### Set Up the Environment
#### MacBook (macOS)
Verify Swift :
```
swift --version
```
#### Linux(Multipartformdata is not supported)
Download Swift for Linux (e.g., Ubuntu) from Swift.org.
```
tar xzf filename
export PATH=$PWD/filename/usr/bin:$PATH
```
Verify:
```
swift --version
```
Install Dependencies:
```
sudo apt-get update
sudo apt-get install clang libicu-dev libcurl4-openssl-dev
```
### Create a Project:
```
mkdir URLSessionDemo
cd URLSessionDemo
swift package init --type executable
```
### Run the Code
Ensure main.swift is in Sources/URLSessionDemo.
Run:
```
swift run
```
## Swift (Alamofire)
### Set Up the Environment
#### MacBook (macOS)
Verify Swift :
```
swift --version
```
#### Linux (Multipartformdata is not supported)
Download Swift for Linux (e.g., Ubuntu) from Swift.org.
```
tar xzf filename
export PATH=$PWD/filename/usr/bin:$PATH
```
Verify:
```
swift --version
```
Install Dependencies for swift:
```
sudo apt-get update
sudo apt-get install clang libicu-dev libcurl4-openssl-dev
```
### Create a Project:
```
mkdir URLSessionDemo
cd URLSessionDemo
swift package init --type executable
```
### Adding alamofire
open `package.swift` and add following dependencies and target(replace `project-name` with your project name)
```
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire", from: "5.6.4")
],
targets: [
.executableTarget(
name: "project-name",
dependencies: [
"Alamofire"
]
)
]
```
### Run the Code
Ensure main.swift is in Sources/URLSessionDemo.
Run:
```
swift run
```
TODO

View File

@ -30,6 +30,7 @@ import 'rust/curl_rust.dart';
import 'rust/hyper.dart';
import 'rust/reqwest.dart';
import 'rust/ureq.dart';
import 'swift/alamofire.dart';
import 'swift/urlsession.dart';
class Codegen {
@ -115,6 +116,8 @@ class Codegen {
return CSharpRestSharp().getCode(rM);
case CodegenLanguage.phpHttpPlug:
return PhpHttpPlugCodeGen().getCode(rM);
case CodegenLanguage.swiftAlamofire:
return SwiftAlamofireCodeGen().getCode(rM);
case CodegenLanguage.swiftUrlSession:
return SwiftURLSessionCodeGen().getCode(rM);
}

View File

@ -0,0 +1,148 @@
import 'package:apidash_core/apidash_core.dart';
import 'package:jinja/jinja.dart' as jj;
import 'package:path/path.dart' as path;
class SwiftAlamofireCodeGen {
final String kTemplateStart = """
import Foundation
import Alamofire
""";
final String kTemplateFormData = '''
let multipartFormData = MultipartFormData()
{% for param in formData %} {% if param.type == 'text' %}multipartFormData.append(Data("{{param.value}}".utf8), withName: "{{param.name}}") {% elif param.type == 'file' %}
let fileURL = URL(fileURLWithPath: "{{param.filepath}}")
multipartFormData.append(fileURL, withName: "{{param.name}}", fileName: "{{param.filename}}", mimeType: "application/octet-stream")
{% endif %}
{% endfor %}
''';
final String kTemplateJsonData = '''
let jsonString = """
{{jsonData}}
"""
let jsonData = jsonString.data(using: .utf8)\n
''';
final String kTemplateTextData = '''
let textString = """
{{textData}}
"""
let textData = textString.data(using: .utf8)\n
''';
final String kTemplateRequest = """
let url = "{{url}}"
{% if hasFormData %}
AF.upload(multipartFormData: multipartFormData, to: url, method: .{{method}}{% if hasHeaders %}, headers: {{headers}}{% endif %})
{% elif hasBody %}
AF.upload({% if hasJsonData %}jsonData{% else %}textData{% endif %}!, to: url, method: .{{method}}{% if hasHeaders %}, headers: {{headers}}{% endif %})
{% else %}
AF.request(url, method: .{{method}}{% if hasHeaders %}, headers: {{headers}}{% endif %})
{% endif %}
.responseData { response in
switch response.result {
case .success(let data):
if let responseString = String(data: data, encoding: .utf8) {
print("Response: \\(responseString)")
}
case .failure(let error):
print("Error: \\(error)")
}
exit(0)
}
dispatchMain()
""";
String? getCode(HttpRequestModel requestModel) {
try {
String result = kTemplateStart;
var rec =
getValidRequestUri(requestModel.url, requestModel.enabledParams);
Uri? uri = rec.$1;
var headers = requestModel.enabledHeadersMap;
bool hasBody = false;
bool hasJsonData = false;
if (requestModel.hasFormData) {
var formDataList = requestModel.formDataMapList.map((param) {
if (param['type'] == 'file') {
final filePath = param['value'] as String;
final fileName = path.basename(filePath);
return {
'type': 'file',
'name': param['name'],
'filename': fileName,
'filepath': filePath
};
} else {
return {
'type': 'text',
'name': param['name'],
'value': param['value']
};
}
}).toList();
var templateFormData = jj.Template(kTemplateFormData);
result += templateFormData.render({
"formData": formDataList,
});
hasBody = true;
} else if (requestModel.hasJsonData) {
var templateJsonData = jj.Template(kTemplateJsonData);
result += templateJsonData.render({
"jsonData":
requestModel.body!.replaceAll('"', '\\"').replaceAll('\n', '\\n'),
});
headers.putIfAbsent("Content-Type", () => "application/json");
hasBody = true;
hasJsonData = true;
}
// Handle text data
else if (requestModel.hasTextData) {
var templateTextData = jj.Template(kTemplateTextData);
result += templateTextData.render({
"textData":
requestModel.body!.replaceAll('"', '\\"').replaceAll('\n', '\\n'),
});
headers.putIfAbsent(
kHeaderContentType, () => requestModel.bodyContentType.header);
hasBody = true;
}
String headersString = "nil";
bool hasHeaders = false;
if (headers.isNotEmpty) {
List<String> headerItems = [];
headers.forEach((key, value) {
headerItems.add('"$key": "$value"');
});
headersString = "[${headerItems.join(', ')}]";
hasHeaders = true;
}
var templateRequest = jj.Template(kTemplateRequest);
result += templateRequest.render({
"url": uri.toString(),
"method": requestModel.method.name.toLowerCase(),
"headers": headersString,
"hasHeaders": hasHeaders,
"hasFormData": requestModel.hasFormData,
"hasBody": hasBody,
"hasJsonData": hasJsonData
});
return result;
} catch (e) {
return null;
}
}
}

View File

@ -132,6 +132,7 @@ enum CodegenLanguage {
rustReqwest("Rust (reqwest)", "rust", "rs"),
rustCurl("Rust (curl-rust)", "rust", "rs"),
rustUreq("Rust (ureq)", "rust", "rs"),
swiftAlamofire("Swift (Alamofire)", "swift", "swift"),
swiftUrlSession("Swift (URLSession)", "swift", "swift");
const CodegenLanguage(this.label, this.codeHighlightLang, this.ext);

File diff suppressed because it is too large Load Diff