Skip to content

Commit dd6288f

Browse files
committed
Draft of migration guide
1 parent fe4cda4 commit dd6288f

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

Docs/1.0 Migration Guide.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,137 @@
11
# TRON 1.0 Migration Guide
2+
3+
## Wrapping Alamofire
4+
5+
Starting from the beginning, `TRON` was a wrapper around [Alamofire](https://github.com/Alamofire/Alamofire). In 0.x releases we tried to hide this fact behind our own constructs and API facade. Basically, we took similar approach to [Moya](https://github.com/Moya/Moya) framework. And while usually completely hiding implementation details from the client is a good idea, we no longer feel it's viable in this current case.
6+
7+
The benefits of facade approach is understandable - you need to only study one framework instead of two. However facade leads to several problems, here are some of them:
8+
9+
#### Code duplication
10+
11+
To completely hide implementation details from the client, you need to provide your own abstractions, that are basically copies of internal framework, for example, here's [some code from Moya](https://github.com/Moya/Moya/blob/72251f8910071568c626a61ad587367a1afb1e49/Source/Moya.swift#L8-L10). HTTP methods that we all know, are basically a duplicated enum from Alamofire, that can be easily removed.
12+
13+
#### Incomplete functionality
14+
15+
API facade is somewhat limited in terms of functionality. It's hard to wrap every single piece of Alamofire. And there's functionality, for example multipart upload, that heavily uses Alamofire data structures and therefore is very hard to implement in API facade. This is probably one of the reasons multipart upload takes a **year** [to implement](https://github.com/Moya/Moya/issues/114) in Moya. And when Alamofire introduces new feature, it takes even longer to port it to a wrapper.
16+
17+
#### Hard customization
18+
19+
Using facade sometimes locks you into artificial barriers that are created only to prevent you from knowing that you are using Alamofire. For example, there's a feature on Alamofire.Request, that allows you to print it's cURL to console using debugDescription variable. However, if used through API facade, you no longer know that you are using Alamofire.Request, then how do you allow using such feature without major headaches?
20+
21+
### Our solution
22+
23+
Starting with 1.0 release, we no longer hide Alamofire.Request from developer. So now, you can do this:
24+
25+
```swift
26+
request.perform(success: { result in })?.responseString { string in
27+
print(string)
28+
}.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
29+
print(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
30+
}
31+
```
32+
33+
`RequestToken` protocol is removed, all perform request method return Alamofire.Request?, which will be nil in case request was stubbed.
34+
35+
Previously, progress closure was included into `MultipartAPIRequest` `perform` method. Now, since it's available on returned Alamofire.Request property, method is reworked:
36+
37+
```
38+
// Old:
39+
let request : MultipartAPIRequest<User,MyAppError> = tron.multipartRequest(path: "profile")
40+
multipartRequest.appendMultipartData(data, name: "avatar", filename: "avatar.jpg", mimeType: "image/jpeg")
41+
request.performWithSuccess({ user in
42+
print("user avatar updated!")
43+
},
44+
failure: { error in
45+
print("failed to upload user avatar")
46+
},
47+
progress: { progress in
48+
print("Picture is uploading, progress: \(CGFloat(progress.totalBytesWritten) / CGFloat(progress.totalBytesExpectedToWrite))")
49+
})
50+
51+
// New:
52+
let request: MultipartAPIRequest<User,MyAppError> = tron.uploadMultipart(path: "profile") { formData in
53+
formData.appendBodyPart(data: data,name: "avatar", mimeType: "image/jpeg")
54+
}
55+
request.performMultipart(success: { user in
56+
print("user avatar updated!")
57+
},
58+
failure: { error in
59+
print("failed to upload user avatar")
60+
}, encodingCompletion: { completion in
61+
if case let Manager.MultipartFormDataEncodingResult.Success(request,_,_) = completion {
62+
request.progress { _, totalBytesWritten, totalBytesExpectedToWrite in
63+
print("Picture is uploading, progress: \(CGFloat(totalBytesWritten) / CGFloat(totalBytesExpectedToWrite))")
64+
}
65+
}
66+
})
67+
```
68+
69+
## New features
70+
71+
We are committed to providing all features Alamofire has to the framework user, and wrapping them into our convenience structures. 1.0 release has full support for download and upload tasks:
72+
73+
#### Upload
74+
75+
From file:
76+
77+
* From file:
78+
79+
```swift
80+
let request = tron.upload(path: "photo", file: fileUrl)
81+
```
82+
83+
* NSData:
84+
85+
```swift
86+
let request = tron.upload(path: "photo", data: data)
87+
```
88+
89+
* Stream:
90+
91+
```swift
92+
let request = tron.upload(path: "photo", stream: stream)
93+
```
94+
95+
#### Download
96+
97+
```swift
98+
let request = tron.download(path: "file", destination: destination)
99+
```
100+
101+
Resume downloads:
102+
103+
```swift
104+
let request = tron.download(path: "file", destination: destination, resumingFromData: data)
105+
```
106+
107+
#### Performing uploads and downloads
108+
109+
All downloads and uploads(except for multipart) use the same `APIRequest` method:
110+
111+
```swift
112+
request.perform(success: { result in }, failure: { error in })
113+
```
114+
115+
Old `performWithSuccess(_:failure:)` method is deprecated and will be removed in future releases.
116+
117+
#### Perform with completion block
118+
119+
Since we no longer hide Alamofire from developer, we are now able to provide perform method with Alamofire completion block, which can be used in several useful ways, for example observing request timeline:
120+
121+
```swift
122+
request.perform(completion: { response in
123+
print(response.result) // Alamofire.Result
124+
print(response.timeline) // Alamofire.Timeline
125+
print(response.response) // NSHTTPURLResponse?
126+
})
127+
```
128+
129+
### Miscellaneous API improvements
130+
131+
Previously, `MultipartAPIRequest` was a subclass of `APIRequest`, which allowed to define it's variable as `APIRequest`, and potentially could lead to runtime crash with improper use. Now, both `MultipartAPIRequest` and `APIRequest` subclass `BaseRequest`, thus preventing this use case.
132+
133+
`Progress` and `ProgressClosure` typealiases are removed, since `TRON` framework no longer handles any progress closures.
134+
135+
`EventDispatcher` class, `TRON.dispatcher` and `APIRequest.dispatcher` properties are replaced with `processingQueue` and `resultDeliveryQueue` properties on `TRON` and `APIRequest`. `processingQueue` property determines on which queue should response parsing proceed, and `resultDeliveryQueue` determines on which queue completion blocks should be called.
136+
137+
`RxSwift` extension `rxMultipartResult()` method on `MultipartAPIRequest` now returns Observable<ModelType> instead of tuple of observables.

0 commit comments

Comments
 (0)