Skip to content

Commit ae1efe8

Browse files
Merge remote-tracking branch 'origin/master' into release
2 parents 05fd553 + 5cff023 commit ae1efe8

File tree

173 files changed

+8522
-6914
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+8522
-6914
lines changed

AsposeWordsCloud.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'AsposeWordsCloud'
3-
s.version = '20.9'
3+
s.version = '20.10'
44
s.summary = 'Aspose Words for Cloud.'
55
s.homepage = 'https://github.com/aspose-words-cloud/aspose-words-cloud-swift.git'
66
s.license = { :type => 'MIT', :file => 'LICENSE' }

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ Add link to this repository as dependency to your Package.swift:
9494

9595
dependencies: [
9696
// Dependencies declare other packages that this package depends on.
97-
.package(url: "https://github.com/aspose-words-cloud/aspose-words-cloud-swift", from: "20.9"),
97+
.package(url: "https://github.com/aspose-words-cloud/aspose-words-cloud-swift", from: "20.10"),
9898
],
9999
targets: [
100100
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@@ -112,7 +112,7 @@ targets: [
112112
Add link to git repository as dependency to your Podfile:
113113

114114
```ruby
115-
pod 'AsposeWordsCloud', :git => 'https://github.com/aspose-words-cloud/aspose-words-cloud-swift.git', :tag => '20.9'
115+
pod 'AsposeWordsCloud', :git => 'https://github.com/aspose-words-cloud/aspose-words-cloud-swift.git', :tag => '20.10'
116116
```
117117

118118
## Getting Started

Sources/AsposeWordsCloud/Api/ApiInvoker.swift

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -71,59 +71,20 @@ public class ApiInvoker {
7171
}
7272

7373
// Invoke request to the API with the specified set of arguments and execute callback after the request is completed
74-
public func invoke(
75-
url: URL,
76-
method: String,
77-
body: Data?,
78-
headers: Dictionary<String, String>?,
79-
formParams: [RequestFormParam]?,
80-
contentType: String = "application/json",
81-
callback: @escaping (_ response: Data?, _ error: Error?) -> ()
74+
public func invoke(apiRequestData : WordsApiRequestData, callback: @escaping (_ response: Data?, _ error: Error?) -> ()
8275
) {
8376
// Create URL request object
84-
var request = URLRequest(url: url);
85-
request.httpMethod = method;
77+
var request = URLRequest(url: apiRequestData.getURL());
78+
request.httpMethod = apiRequestData.getMethod();
8679

8780
// Fill headers
88-
if (headers != nil) {
89-
for (key, value) in headers! {
90-
request.setValue(value, forHTTPHeaderField: key);
91-
}
81+
for (key, value) in apiRequestData.getHeaders() {
82+
request.setValue(value, forHTTPHeaderField: key);
9283
}
9384

9485
// Process the request body
95-
if (body != nil) {
96-
request.httpBody = body;
97-
request.setValue(contentType, forHTTPHeaderField: "Content-Type");
98-
}
99-
else if (formParams != nil && formParams!.count > 0) {
100-
if (formParams?.count == 1) {
101-
request.httpBody = (formParams!)[0].getBody();
102-
}
103-
else {
104-
// Generate body for multiform requests
105-
var needsClrf = false;
106-
var formBody = Data();
107-
let boundaryPrefix = "Somthing";
108-
for formParam in formParams! {
109-
if (needsClrf) {
110-
formBody.append("\r\n".data(using: .utf8)!);
111-
}
112-
needsClrf = true;
113-
114-
formBody.append("--\(boundaryPrefix)\r\nContent-Disposition: form-data; name=\"\(formParam.getName())\"\r\n\r\n".data(using: .utf8)!);
115-
formBody.append(formParam.getBody());
116-
}
117-
formBody.append("\r\n--\(boundaryPrefix)--\r\n".data(using: .utf8)!);
118-
119-
request.httpBody = formBody;
120-
request.setValue("multipart/form-data; boundary=\(boundaryPrefix)", forHTTPHeaderField: "Content-Type");
121-
}
122-
}
123-
124-
// Set content length header
125-
if (request.httpBody != nil) {
126-
request.setValue(String(request.httpBody!.count), forHTTPHeaderField: "Content-Length");
86+
if (apiRequestData.getBody() != nil) {
87+
request.httpBody = apiRequestData.getBody();
12788
}
12889

12990
// Request or get from cache authorization token

Sources/AsposeWordsCloud/Api/Configuration.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,6 @@ public class Configuration : Codable {
9191

9292
// Returns SDK version for using in statistics headers
9393
public func getSdkVersion() -> String {
94-
return "20.9";
94+
return "20.10";
9595
}
9696
}

Sources/AsposeWordsCloud/Api/ObjectSerializer.swift

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,107 @@ class ObjectSerializer {
130130
return try customDecoder.decode(type, from: data);
131131
}
132132

133+
// Deserialize an multipart response
134+
public static func parseMultipart(data: Data) throws -> [ResponseFormParam] {
135+
var result = [ResponseFormParam]();
136+
if (!data.starts(with: "--".data(using: .utf8)!)) {
137+
throw WordsApiError.invalidMultipartResponse(message: "Boundary not found");
138+
}
139+
140+
let newLineData = "\r\n".data(using: .utf8)!;
141+
let boundaryEndIndex = data.range(of: newLineData);
142+
if (boundaryEndIndex == nil || boundaryEndIndex!.isEmpty) {
143+
throw WordsApiError.invalidMultipartResponse(message: "Boundary not found");
144+
}
145+
146+
let boundary = data.subdata(in: data.startIndex..<boundaryEndIndex!.lowerBound);
147+
let parts = ObjectSerializer.splitData(data: data, separator: boundary);
148+
let dispositionSeparator = "\r\n\r\n".data(using: .utf8)!;
149+
150+
for part in parts {
151+
let partDataBounds = part.range(of: dispositionSeparator);
152+
if (partDataBounds == nil || partDataBounds!.isEmpty) {
153+
throw WordsApiError.invalidMultipartResponse(message: "Part content not found");
154+
}
155+
156+
let headData = part.subdata(in: part.startIndex..<partDataBounds!.lowerBound);
157+
let headContent = String(decoding: headData, as: UTF8.self);
158+
var headers = [String : String]();
159+
160+
for headerRawData in headContent.components(separatedBy: "\r\n") {
161+
let headerData = headerRawData.trimmingCharacters(in: .whitespacesAndNewlines);
162+
if (!headerData.isEmpty) {
163+
let headerParts = headerData.split(separator: ":");
164+
if (headerParts.count == 2) {
165+
let headerKey = headerParts[0].trimmingCharacters(in: .whitespaces);
166+
let headerValue = headerParts[1].trimmingCharacters(in: .whitespaces);
167+
headers[headerKey] = headerValue;
168+
}
169+
}
170+
}
171+
172+
let bodyData = part.subdata(in: partDataBounds!.upperBound..<part.endIndex);
173+
result.append(ResponseFormParam(body: bodyData, headers: headers));
174+
}
175+
176+
return result;
177+
}
178+
179+
// Split data into parts
180+
public static func splitData(data: Data, separator: Data) -> [Data] {
181+
let endIndex = separator.count;
182+
var chunks: [Data] = [];
183+
var pos = 0;
184+
while let r = data[pos...].range(of: separator) {
185+
if (r.lowerBound > pos) {
186+
chunks.append(data[pos..<r.lowerBound]);
187+
}
188+
189+
pos = r.upperBound;
190+
}
191+
192+
if (pos < endIndex) {
193+
chunks.append(data[pos..<endIndex]);
194+
}
195+
196+
return chunks;
197+
}
198+
199+
// Create an instance of T, from batch part data
200+
public static func deserializeBatchPart(request: WordsApiRequest, partData: ResponseFormParam) throws -> Any? {
201+
let separator = "\r\n\r\n".data(using: .utf8)!;
202+
let data = partData.getBody();
203+
let partDataBounds = data.range(of: separator);
204+
if (partDataBounds == nil || partDataBounds!.isEmpty) {
205+
throw WordsApiError.invalidMultipartResponse(message: "Body content not found");
206+
}
207+
208+
let headData = data.subdata(in: data.startIndex..<partDataBounds!.lowerBound);
209+
let headContent = String(decoding: headData, as: UTF8.self);
210+
let headParts = headContent.components(separatedBy: "\r\n");
211+
if (headParts.count == 0) {
212+
throw WordsApiError.invalidMultipartResponse(message: "Head content not found");
213+
}
214+
215+
let codeContent = headParts[0].split(separator: " ", maxSplits: 1, omittingEmptySubsequences: true);
216+
if (codeContent.count != 2) {
217+
throw WordsApiError.invalidMultipartResponse(message: "Head content not found");
218+
}
219+
220+
let codeStatus = Int(codeContent[0]);
221+
if (codeStatus == nil) {
222+
throw WordsApiError.invalidMultipartResponse(message: "Failed to parse head content");
223+
}
224+
225+
let bodyData = data.subdata(in: partDataBounds!.upperBound..<data.endIndex);
226+
if (codeStatus != 200) {
227+
let errorMessage = String(decoding: bodyData, as: UTF8.self);
228+
return WordsApiError.requestError(errorCode: codeStatus!, message: errorMessage);
229+
}
230+
231+
return try request.deserializeResponse(data: bodyData);
232+
}
233+
133234
// Configuration for DateTime serialization/deserialization
134235
public static let customIso8601: DateFormatter = {
135236
let formatter = DateFormatter()

Sources/AsposeWordsCloud/Api/RequestFormParam.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,25 @@ import Foundation
2929

3030
// Represent struct for using as form param in request
3131
public struct RequestFormParam {
32-
private let name : String;
32+
private let name : String?;
3333
private let body : Data;
34+
private let contentType : String;
3435

35-
public init(name : String, body : Data) {
36+
public init(name : String?, body : Data, contentType : String) {
3637
self.name = name;
3738
self.body = body;
39+
self.contentType = contentType;
3840
}
3941

40-
public func getName() -> String {
42+
public func getName() -> String? {
4143
return self.name;
4244
}
4345

4446
public func getBody() -> Data {
4547
return self.body;
4648
}
49+
50+
public func getContentType() -> String {
51+
return self.contentType;
52+
}
4753
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* --------------------------------------------------------------------------------
3+
* <copyright company="Aspose" file="ResponseFormParam.swift">
4+
* Copyright (c) 2020 Aspose.Words for Cloud
5+
* </copyright>
6+
* <summary>
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in all
15+
* copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
* SOFTWARE.
24+
* </summary>
25+
* --------------------------------------------------------------------------------
26+
*/
27+
28+
import Foundation
29+
30+
// Represent struct for using as form param in request
31+
public struct ResponseFormParam {
32+
private let body : Data;
33+
private let headers : [String : String];
34+
35+
public init(body : Data, headers : [String : String]) {
36+
self.body = body;
37+
self.headers = headers;
38+
}
39+
40+
public func getBody() -> Data {
41+
return self.body;
42+
}
43+
44+
public func getHeaders() -> [String : String] {
45+
return self.headers;
46+
}
47+
}

0 commit comments

Comments
 (0)