Skip to content

Commit 76ad606

Browse files
committed
fix: sending success when error
1 parent f0b9b73 commit 76ad606

File tree

3 files changed

+116
-59
lines changed

3 files changed

+116
-59
lines changed

IONFileTransferLib/Delegates/IONFLTRUploadDelegate.swift

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ class IONFLTRUploadDelegate: IONFLTRBaseDelegate {
1010

1111
/// The total number of bytes sent during the upload.
1212
private var totalBytesSent: Int = 0
13+
14+
/// The data received from the server during the upload.
15+
private lazy var receivedData: Data = Data()
16+
1317

1418
/// Initializes a new instance of the `IONFLTRUploadDelegate` class.
1519
///
@@ -43,7 +47,38 @@ extension IONFLTRUploadDelegate: URLSessionDataDelegate {
4347
/// - task: The `URLSessionTask` that completed.
4448
/// - error: The error that occurred, if any.
4549
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: (any Error)?) {
46-
super.handleCompletion(task: task, error: error)
50+
if let error = error {
51+
super.handleCompletion(task: task, error: error)
52+
return
53+
}
54+
55+
let response = task.response as? HTTPURLResponse
56+
let statusCode = response?.statusCode ?? 0
57+
let responseData = String(data: receivedData, encoding: .utf8)
58+
let headers = response?.allHeaderFields.reduce(into: [String: String]()) { result, element in
59+
if let key = element.key as? String, let value = element.value as? String {
60+
result[key] = value
61+
}
62+
} ?? [:]
63+
64+
if (200...299).contains(statusCode) {
65+
publisher.sendSuccess(
66+
totalBytes: totalBytesSent,
67+
responseCode: statusCode,
68+
responseBody: responseData,
69+
headers: headers
70+
)
71+
} else {
72+
publisher.sendFailure(
73+
IONFLTRException.httpError(
74+
responseCode: statusCode,
75+
responseBody: nil,
76+
headers: headers
77+
)
78+
)
79+
}
80+
81+
receivedData = Data() // Reset received data for next upload
4782
}
4883

4984
/// Handles HTTP redirection for a task.
@@ -65,20 +100,6 @@ extension IONFLTRUploadDelegate: URLSessionDataDelegate {
65100
/// - dataTask: The `URLSessionDataTask` that received the data.
66101
/// - data: The data received from the server.
67102
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
68-
let response = dataTask.response as? HTTPURLResponse
69-
let statusCode = response?.statusCode ?? 0
70-
let responseData = String(data: data, encoding: .utf8)
71-
let headers = response?.allHeaderFields.reduce(into: [String: String]()) { result, element in
72-
if let key = element.key as? String, let value = element.value as? String {
73-
result[key] = value
74-
}
75-
} ?? [:]
76-
77-
publisher.sendSuccess(
78-
totalBytes: totalBytesSent,
79-
responseCode: statusCode,
80-
responseBody: responseData,
81-
headers: headers
82-
)
103+
receivedData.append(data)
83104
}
84105
}

IONFileTransferLibTests/Delegates/IONFLTRUploadDelegateTests.swift

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -93,35 +93,37 @@ final class IONFLTRUploadDelegateTests: XCTestCase {
9393
waitForExpectations(timeout: 1)
9494
}
9595

96-
func testDidReceiveData_shouldCallSendSuccess() {
97-
class MockDataTask: URLSessionDataTask, @unchecked Sendable {
98-
private let mockResponse: URLResponse?
99-
100-
override var response: URLResponse? {
101-
return mockResponse
102-
}
103-
104-
init(response: URLResponse?) {
105-
self.mockResponse = response
106-
super.init()
107-
}
108-
}
96+
func testDidReceiveData_shouldAccumulateData() {
97+
let data1 = "Part1".data(using: .utf8)!
98+
let data2 = "Part2".data(using: .utf8)!
10999

110-
let expectedResponseBody = "Success!"
111-
let data = expectedResponseBody.data(using: .utf8)!
112100
let task = URLSession.shared.dataTask(with: URL(string: "https://example.com")!)
113101

114-
let urlResponse = HTTPURLResponse(url: task.originalRequest!.url!, statusCode: 200, httpVersion: nil, headerFields: ["Content-Type": "text/plain"])
115-
let dataTask = MockDataTask(response: urlResponse)
102+
delegate.urlSession(URLSession.shared, dataTask: task, didReceive: data1)
103+
delegate.urlSession(URLSession.shared, dataTask: task, didReceive: data2)
104+
105+
// Simular o fim da requisição para forçar leitura do responseBody
106+
let response = HTTPURLResponse(
107+
url: task.originalRequest!.url!,
108+
statusCode: 200,
109+
httpVersion: nil,
110+
headerFields: ["Content-Type": "text/plain"]
111+
)
112+
113+
class MockTask: URLSessionTask, @unchecked Sendable {
114+
let mockResponse: URLResponse?
115+
override var response: URLResponse? { return mockResponse }
116+
init(response: URLResponse?) { self.mockResponse = response }
117+
}
116118

117-
delegate.urlSession(URLSession.shared, dataTask: dataTask, didReceive: data)
119+
let mockTask = MockTask(response: response)
120+
delegate.urlSession(URLSession.shared, task: mockTask, didCompleteWithError: nil)
118121

119122
let result = mockPublisher.successCalled
120-
XCTAssertEqual(result?.0, 0) // totalBytesSent should still be 0
121-
XCTAssertEqual(result?.1, 200)
122-
XCTAssertEqual(result?.2, expectedResponseBody)
123+
XCTAssertEqual(result?.2, "Part1Part2")
123124
XCTAssertEqual(result?.3["Content-Type"], "text/plain")
124125
}
126+
125127

126128
func testDidCompleteWithError_Non2xxStatusCode() {
127129
class MockURLSessionTask: URLSessionTask, @unchecked Sendable {
@@ -152,9 +154,32 @@ final class IONFLTRUploadDelegateTests: XCTestCase {
152154
)
153155
}
154156

155-
func testDidCompleteWithError_withoutError_shouldNotSendFailure() {
156-
delegate.urlSession(URLSession.shared, task: URLSessionDataTask(), didCompleteWithError: nil)
157+
func testDidCompleteWithSuccess_shouldSendSuccess() {
158+
let responseBody = "Uploaded!"
159+
let data = responseBody.data(using: .utf8)!
157160

158-
XCTAssertNil(mockPublisher.failureCalled)
161+
let task = URLSession.shared.dataTask(with: URL(string: "https://example.com")!)
162+
delegate.urlSession(URLSession.shared, dataTask: task, didReceive: data)
163+
164+
class MockTask: URLSessionTask {
165+
let mockResponse: URLResponse?
166+
override var response: URLResponse? { return mockResponse }
167+
init(response: URLResponse?) { self.mockResponse = response }
168+
}
169+
170+
let mockResponse = HTTPURLResponse(
171+
url: URL(string: "https://example.com")!,
172+
statusCode: 201,
173+
httpVersion: nil,
174+
headerFields: ["X-Custom": "value"]
175+
)
176+
let mockTask = MockTask(response: mockResponse)
177+
178+
delegate.urlSession(URLSession.shared, task: mockTask, didCompleteWithError: nil)
179+
180+
XCTAssertEqual(mockPublisher.successCalled?.0, 0) // totalBytesSent is default 0
181+
XCTAssertEqual(mockPublisher.successCalled?.1, 201)
182+
XCTAssertEqual(mockPublisher.successCalled?.2, responseBody)
183+
XCTAssertEqual(mockPublisher.successCalled?.3["X-Custom"], "value")
159184
}
160185
}

scripts/build.sh

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
1-
cd ..
1+
BUILD_FOLDER="build"
2+
BUILD_SCHEME="IONFileTransferLib"
3+
FRAMEWORK_NAME="IONFileTransferLib"
4+
SIMULATOR_ARCHIVE_PATH="${BUILD_FOLDER}/iphonesimulator.xcarchive"
5+
IOS_DEVICE_ARCHIVE_PATH="${BUILD_FOLDER}/iphoneos.xcarchive"
26

3-
rm -rf build
7+
rm -rf "${FRAMEWORK_NAME}.zip"
8+
rm -rf ${BUILD_FOLDER}
49

510
xcodebuild archive \
6-
-scheme IONFileTransferLib \
7-
-configuration Release \
8-
-destination 'generic/platform=iOS Simulator' \
9-
-archivePath './scripts/build/IONFileTransferLib.framework-iphonesimulator.xcarchive' \
10-
SKIP_INSTALL=NO \
11-
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
12-
11+
-scheme ${BUILD_SCHEME} \
12+
-configuration Release \
13+
-destination 'generic/platform=iOS Simulator' \
14+
-archivePath "./${SIMULATOR_ARCHIVE_PATH}/" \
15+
SKIP_INSTALL=NO \
16+
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
1317

1418
xcodebuild archive \
15-
-scheme IONFileTransferLib \
16-
-configuration Release \
17-
-destination 'generic/platform=iOS' \
18-
-archivePath './scripts/build/IONFileTransferLib.framework-iphoneos.xcarchive' \
19-
SKIP_INSTALL=NO \
20-
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
21-
19+
-scheme ${BUILD_SCHEME} \
20+
-configuration Release \
21+
-destination 'generic/platform=iOS' \
22+
-archivePath "./${IOS_DEVICE_ARCHIVE_PATH}/" \
23+
SKIP_INSTALL=NO \
24+
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
2225

2326
xcodebuild -create-xcframework \
24-
-framework './scripts/build/IONFileTransferLib.framework-iphonesimulator.xcarchive/Products/Library/Frameworks/IONFileTransferLib.framework' \
25-
-framework './scripts/build/IONFileTransferLib.framework-iphoneos.xcarchive/Products/Library/Frameworks/IONFileTransferLib.framework' \
26-
-output './scripts/build/IONFileTransferLib.xcframework'
27+
-framework "./${SIMULATOR_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework" \
28+
-debug-symbols "${PWD}/${SIMULATOR_ARCHIVE_PATH}/dSYMs/${FRAMEWORK_NAME}.framework.dSYM" \
29+
-framework "./${IOS_DEVICE_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework" \
30+
-debug-symbols "${PWD}/${IOS_DEVICE_ARCHIVE_PATH}/dSYMs/${FRAMEWORK_NAME}.framework.dSYM" \
31+
-output "./${BUILD_FOLDER}/${FRAMEWORK_NAME}.xcframework"
32+
33+
cp LICENSE ${BUILD_FOLDER}
34+
35+
cd "./${BUILD_FOLDER}"
36+
37+
zip -r "${FRAMEWORK_NAME}.zip" "${FRAMEWORK_NAME}.xcframework" LICENSE

0 commit comments

Comments
 (0)