Skip to content

Commit c2116f7

Browse files
makoniivantsersedykh
authored
0.10.0 (#108)
* refactoring * refactoring * refactoring * wip * wip * refactoring * wip * wip * wip * wip * wip * version * wip * wip * wip * wip * wip * refactoring * Update test.yml * tests updated * tests updated * tests updated * Carthage build fixed * documentation updated * demo app updated with new lib methods * Readme updated * cleanup * update files list on main thread in demo app * allow setting signature from external source * lib version bump * Update README.md * Update Upload API.md * formatting * Update Upload API.md * custom uploadSignature can be provided for methods: - Upload file from url - Multipart file uploading - Create files group from a set of files - Create files group from a set of files UUIDs. - Files group info * custom uploadSignature can be provided for main uploadFile method that decides which upload method to use internally * custom uploadSignature can be provided for upload method of UploadedFile object * increase timeout for video conversion integration test * documentation updated * Update Sources/Uploadcare/Uploadcare.swift Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update README.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update Documentation/Upload API.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update README.md * Update README.md * Update README.md * Update Upload API.md * Update README.md * Update README.md * Update Upload API.md * Update REST API.md * Update Documentation/REST API.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update Documentation/REST API.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update Documentation/Upload API.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update Documentation/Upload API.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update README.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * Update README.md Co-authored-by: Roman Sedykh <rsedykh@gmail.com> * fixed when storing behavour param was missing for direct upload request * version bump * removed deprecated files for tests * Swift version 5.1 -> 5.6 * removed unused allTests property in tests * refactoring * refactoring * refactoring * bumped api version to 0.7 * - removed sorting by size for getting list of files method - data param for dateTimeUploadedASC ordering is optional now * removed rekognitionInfo from File model * removed imageInfo from File model * removed videoInfo from File model * warning * metadata added to File model * docs * order * Improvements for handling responses in RequestManager * Added methods for REST API to get/update/delete File metadata * store group method is not available for REST API anymore * use keyDecodingStrategy for decoders * Revert "use keyDecodingStrategy for decoders" This reverts commit d210ca2. * added contentInfo property to File data model * delete group method added for REST API * models updated * added FileInfoQuery to set request query to include appdata * new models for AppData added * refactoring * appData field added for File model * refactoring * execute AWS recognition method added * added method to check aws recognition status * integration tests for aws recognition execution and and status check * Added execution of ClamAV addon, checking it’s status and integration tests for it * RemoveBGAddonExecutionParams model added * remove.bg addon execution and status + refactoring * integration tests for remove.bg addon methods * done field added to UploadedFile model * added contentInfo file to UploadedFile model * added metadata property to UploadedFile model * bump lib version * metadata can be provided for upload from url method * metadata can be provided for direct upload method * metadata can be provided for multipart uploads * set swift version 5.5 * demo app fixed * updated project for carthage * more swift versions * podfile updated * warning removed * set lib version 0.9.0 * metadata param for main upload method - metadata param for main upload method - don’t get fileinfo if only public key provided after direct upload integration test for direct upload when only public key provided * pass metadata from UploadedFile when calling upload * added integratin test for multipart uploading if only public key provided * Update README.md * Update REST API.md * Update REST API.md * Update REST API.md * Update REST API.md * Update Upload API.md * Update README.md * Update test.yml * Update REST API.md * Update REST API.md * Update Upload API.md * Update REST API.md * Update REST API.md * couple links updated * test updated * fixed parsing of UploadedFile model * added new integration test to upload a video file and check that parsing of response works * version bump * spaces * cleanup * async tests file * async version of getProjectInfo and test * formatting * async getListOfWebhooks and test * async performRequest * async webhooks methods * refactoring * refactoring * async listOfGroups and groupInfo + tests * async list of files and tests * one more test * async pagination for list of files * async fileinfo and test * error handling * refactoring * refactoring * async groups list and pagination + tests * Equatable conformance * Equatable for Group and check results in test * async getAuthenticatedUrlFromUrl and test * UploadAPIIntegrationAsyncTests * async directUploadInForeground and test * async deleteFile and test * async deleteFiles and test * async storeFile and test * async storeFiles and test * async copyFileToLocalStorage and test * async copyFileToRemoteStorage and test * async convertDocuments, convertDocumentsWithSettings, documentConversionJobStatus and tests * async convertVideosWithSettings, convertVideos, videoConversionJobStatus and tests * … * async methods for metadata and test * Async methods for AWS recognition and test * Async methods for Clamav addon and test * async methods for Remove.bg addon and tests * async deleteGroup method * refactoring * async methods for upload from url and it’s status and test * warning fixed * async fileInfo and test * updated unsplash link * tests refactoring * async multipart upload and test * test improved * uploadSignature param for directUploadInForeground * async uploadFile method in Uploadcare class + test * docs * async upload method for UploadedFile class and test * test updated * async methods to create groups + tests * tests renames * cleanup * tests annotation * fixed build for tvOS * annotation * fixed build for watchOS * tests are available for watchOS too * … * documentation updated * docs * docs * docs * docs * docs * spaces * docs * docs * docs * docs * docs * docs * docs * docs * readme * update semf * demo app refactoring * async * refactoring * more async methods * dead link * more async * widget updated to fix a warning * use new AsyncImage in widget * warning fixed * cleanup * async files load in demo app * discardableResult * async file delete in demo * demo app project updated * readme updated * docs updated * docs updated * test updated * docs with examples * docs * docs * docs * docs * REST API docs * docs * docs * couple fixes * uploadAndWaitForCompletion method and test added * docs * bump lib version * podspec updated * updated carthage project * Update README.md * bump version to 0.10.0 * podspec updated * Update test.yml --------- Co-authored-by: Ivan Tse <github@nerdtower.com> Co-authored-by: Roman Sedykh <rsedykh@gmail.com>
1 parent 416039a commit c2116f7

File tree

74 files changed

+4584
-800
lines changed

Some content is hidden

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

74 files changed

+4584
-800
lines changed

.github/workflows/test.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212

1313
steps:
1414
- name: Checkout
15-
uses: actions/checkout@v2
15+
uses: actions/checkout@v3.5.3
1616

1717
- name: Swift build for iOS
1818
run: swift build -c release -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios13.0-simulator"
@@ -31,7 +31,7 @@ jobs:
3131

3232
steps:
3333
- name: Checkout
34-
uses: actions/checkout@v2
34+
uses: actions/checkout@v3.5.3
3535

3636
- name: Build Carthage target ${{matrix.target}}
3737
run: xcodebuild build -project Uploadcare.xcodeproj -scheme ${{matrix.target}} -configuration Release

Demo/Demo.xcodeproj/project.pbxproj

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 52;
6+
objectVersion = 53;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -64,7 +64,6 @@
6464
24AA61DC247C5B1C000BABA9 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = "<group>"; };
6565
24BAB4382549E4070075E79A /* PickerType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickerType.swift; sourceTree = "<group>"; };
6666
24BAB43B2549E42D0075E79A /* UploadState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadState.swift; sourceTree = "<group>"; };
67-
24BAB4402549E4DA0075E79A /* APIStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIStore.swift; sourceTree = "<group>"; };
6867
24BAB4442549E53A0075E79A /* GroupsListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupsListViewModel.swift; sourceTree = "<group>"; };
6968
24BAB4472549E5AC0075E79A /* FilesListStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilesListStore.swift; sourceTree = "<group>"; };
7069
24BAB44A2549E6270075E79A /* ImageStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageStore.swift; sourceTree = "<group>"; };
@@ -173,7 +172,6 @@
173172
24BAB43E2549E4930075E79A /* Modules */ = {
174173
isa = PBXGroup;
175174
children = (
176-
24BAB4402549E4DA0075E79A /* APIStore.swift */,
177175
24BAB4472549E5AC0075E79A /* FilesListStore.swift */,
178176
24BAB44A2549E6270075E79A /* ImageStore.swift */,
179177
24BAB44D2549E65A0075E79A /* RandomTransformator.swift */,
@@ -253,8 +251,9 @@
253251
243A711E242CEAA200CA229B /* Project object */ = {
254252
isa = PBXProject;
255253
attributes = {
254+
BuildIndependentTargetsInParallel = YES;
256255
LastSwiftUpdateCheck = 1140;
257-
LastUpgradeCheck = 1210;
256+
LastUpgradeCheck = 1430;
258257
ORGANIZATIONNAME = "Uploadcare, Inc";
259258
TargetAttributes = {
260259
243A7125242CEAA200CA229B = {
@@ -476,7 +475,9 @@
476475
);
477476
PRODUCT_BUNDLE_IDENTIFIER = com.uploadcare.Demo;
478477
PRODUCT_NAME = "$(TARGET_NAME)";
478+
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
479479
SUPPORTS_MACCATALYST = YES;
480+
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
480481
SWIFT_VERSION = 5.0;
481482
TARGETED_DEVICE_FAMILY = "1,2";
482483
};
@@ -502,7 +503,9 @@
502503
);
503504
PRODUCT_BUNDLE_IDENTIFIER = com.uploadcare.Demo;
504505
PRODUCT_NAME = "$(TARGET_NAME)";
506+
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
505507
SUPPORTS_MACCATALYST = YES;
508+
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
506509
SWIFT_VERSION = 5.0;
507510
TARGETED_DEVICE_FAMILY = "1,2";
508511
};

Demo/Demo/Models/CollaboratorViewData.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88

99
import Foundation
1010

11-
struct CollaboratorViewData {
11+
struct CollaboratorViewData: Identifiable, Hashable {
1212
// MARK: - Public properties
13+
let id = UUID()
1314
var name: String
1415
var email: String
1516
}

Demo/Demo/Modules/FilesListStore.swift

+23-7
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,34 @@ class FilesListStore: ObservableObject {
3939
}
4040

4141
// MARK: - Public methods
42-
func load(_ completionHandler: @escaping (Result<FilesList, RESTAPIError>) -> Void) {
42+
func load() async throws {
43+
guard let list = list else { fatalError("No list object") }
44+
list.results.removeAll()
45+
4346
let query = PaginationQuery()
4447
.limit(5)
4548
.ordering(.dateTimeUploadedDESC)
46-
47-
self.list?.get(withQuery: query, completionHandler)
49+
50+
try await list.get(withQuery: query)
51+
DispatchQueue.main.async {
52+
list.results.forEach { self.files.append(FileViewData( file: $0)) }
53+
}
4854
}
49-
50-
func loadNext(_ completionHandler: @escaping (Result<FilesList, RESTAPIError>) -> Void) {
51-
self.list?.nextPage(completionHandler)
55+
56+
func loadNext() async throws {
57+
guard let list = list else { fatalError("No list object") }
58+
try await list.nextPage()
59+
DispatchQueue.main.async {
60+
list.results.forEach({ self.files.append(FileViewData( file: $0)) })
61+
}
5262
}
53-
63+
64+
func deleteFiles(at offsets: IndexSet) async throws {
65+
let uuids = offsets.map { self.files[$0].file.uuid }
66+
try await uploadcare?.deleteFiles(withUUIDs: uuids)
67+
DispatchQueue.main.async { self.files.remove(atOffsets: offsets) }
68+
}
69+
5470
func uploadFiles(_ urls: [URL], completionHandler: @escaping ([String])->Void) {
5571
self.filesQueue = urls
5672
var fileIds: [String] = []

Demo/Demo/SceneDelegate.swift

+4-7
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
2424
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
2525
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
2626

27-
// Create the SwiftUI view that provides the window contents.
28-
let contentView = MainView()
29-
3027
// Use a UIHostingController as window root view controller.
3128
if let windowScene = scene as? UIWindowScene {
3229
let window = UIWindow(windowScene: windowScene)
@@ -37,11 +34,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
3734
)
3835

3936
let apiStore = APIStore(uploadcare: uploadcare)
37+
38+
// Create the SwiftUI view that provides the window contents.
39+
let contentView = MainView().environmentObject(apiStore)
4040

41-
window.rootViewController = UIHostingController(
42-
rootView: contentView
43-
.environmentObject(apiStore)
44-
)
41+
window.rootViewController = UIHostingController(rootView: contentView)
4542
self.window = window
4643
window.makeKeyAndVisible()
4744
}

Demo/Demo/ViewModels/GroupsListViewModel.swift

+14-18
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,26 @@ class GroupsListViewModel: ObservableObject {
2929

3030
// MARK: - Public methods
3131
extension GroupsListViewModel {
32-
func loadData() {
32+
func loadData() async throws {
33+
guard let list else { return }
3334
let query = GroupsListQuery()
3435
.limit(5)
3536
.ordering(.datetimeCreatedDESC)
36-
37-
self.list?.get(withQuery: query) { [weak self] result in
38-
switch result {
39-
case .failure(let error):
40-
DLog(error)
41-
case .success(let list):
42-
self?.groups.removeAll()
43-
list.results.forEach { self?.groups.append(GroupViewData(group: $0)) }
37+
38+
let newData = try await list.get(withQuery: query)
39+
DispatchQueue.main.async { [weak self] in
40+
self?.groups.removeAll()
41+
newData.results.forEach {
42+
self?.groups.append(GroupViewData(group: $0))
4443
}
4544
}
4645
}
47-
48-
func loadMoreIfNeed() {
49-
self.list?.nextPage { [weak self] result in
50-
switch result {
51-
case .failure(let error):
52-
DLog(error)
53-
case .success(let list):
54-
list.results.forEach({ self?.groups.append(GroupViewData(group: $0)) })
55-
}
46+
47+
func loadMoreIfNeed() async throws {
48+
guard let list else { return }
49+
let newData = try await list.nextPage()
50+
DispatchQueue.main.async { [weak self] in
51+
newData.results.forEach({ self?.groups.append(GroupViewData(group: $0)) })
5652
}
5753
}
5854
}

Demo/Demo/ViewModels/ProjectInfoViewModel.swift

+6-14
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ProjectInfoViewModel: ObservableObject {
3232

3333
// MARK: - Private properties
3434
private var uploadcare: Uploadcare?
35-
@Published private var projectData: Project?
35+
private var projectData: Project?
3636

3737
// MARK: - Init
3838
init(projectData: Project? = nil, uploadcare: Uploadcare? = nil) {
@@ -42,20 +42,12 @@ class ProjectInfoViewModel: ObservableObject {
4242
}
4343

4444
extension ProjectInfoViewModel {
45-
func loadData(onComplete: @escaping ()->Void) {
46-
guard let api = uploadcare else {
47-
onComplete()
48-
return
49-
}
45+
func loadData() async throws {
46+
guard let api = uploadcare else { return }
47+
let project = try await api.getProjectInfo()
5048

51-
api.getProjectInfo { result in
52-
switch result {
53-
case .failure(let error):
54-
DLog(error)
55-
case .success(let project):
56-
self.projectData = project
57-
onComplete()
58-
}
49+
DispatchQueue.main.async { [weak self] in
50+
self?.projectData = project
5951
}
6052
}
6153
}

Demo/Demo/Views/FilesList/FilesListView.swift

+22-40
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ struct FilesListView: View {
127127
}
128128
EditButton()
129129
}
130-
131130
)
132131
.navigationBarTitle(Text("List of files"))
133132
}
@@ -147,56 +146,39 @@ struct FilesListView: View {
147146

148147
func loadMoreIfNeed() {
149148
self.isLoading = true
150-
filesListStore.loadNext { result in
151-
defer { self.isLoading = false }
149+
Task {
150+
defer { DispatchQueue.main.async { self.isLoading = false } }
152151

153-
switch result {
154-
case .failure(let error):
155-
self.alertMessage = error.detail
156-
self.isShowingAlert.toggle()
157-
DLog(error)
158-
case .success(let list):
159-
DispatchQueue.main.async {
160-
list.results.forEach({ self.filesListStore.files.append(FileViewData( file: $0)) })
161-
}
152+
do {
153+
try await filesListStore.loadNext()
154+
} catch let error {
155+
DispatchQueue.main.async {
156+
self.alertMessage = (error as? RESTAPIError)?.detail ?? error.localizedDescription
157+
self.isShowingAlert.toggle()
158+
}
162159
}
163160
}
164161
}
165162

166163
func delete(at offsets: IndexSet) {
167-
offsets.forEach { (index) in
168-
let fileView = filesListStore.files[index]
169-
let uuid = fileView.file.uuid
170-
171-
self.api.uploadcare?.deleteFile(withUUID: uuid) { result in
172-
switch result {
173-
case .failure(let error):
174-
DLog(error)
175-
case .success(_):
176-
break
177-
}
178-
}
179-
}
180-
181-
filesListStore.files.remove(atOffsets: offsets)
164+
Task {
165+
try await self.filesListStore.deleteFiles(at: offsets)
166+
}
182167
}
183168

184169
func loadData() {
185170
filesListStore.uploadcare = self.api.uploadcare
186-
filesListStore.load { result in
187-
defer { self.isLoading = false }
171+
Task {
172+
defer { DispatchQueue.main.async { self.isLoading = false } }
188173

189-
switch result {
190-
case .failure(let error):
191-
self.alertMessage = error.detail
192-
self.isShowingAlert.toggle()
193-
DLog(error)
194-
case .success(let list):
195-
self.didLoadData = true
196-
DispatchQueue.main.async {
197-
self.filesListStore.files.removeAll()
198-
list.results.forEach { self.filesListStore.files.append(FileViewData( file: $0)) }
199-
}
174+
do {
175+
try await self.filesListStore.load()
176+
DispatchQueue.main.async { self.didLoadData = true }
177+
} catch let error {
178+
DispatchQueue.main.async {
179+
self.alertMessage = (error as? RESTAPIError)?.detail ?? error.localizedDescription
180+
self.isShowingAlert.toggle()
181+
}
200182
}
201183
}
202184
}

Demo/Demo/Views/GroupsList/GroupFileList.swift

+15-21
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct GroupFileList: View {
3737
.onAppear {
3838
guard self.didLoadData == false else { return }
3939
self.didLoadData = true
40-
self.loadData()
40+
Task { try await self.loadData() }
4141
}
4242
.alert(isPresented: $isShowingAlert) {
4343
Alert(
@@ -49,31 +49,25 @@ struct GroupFileList: View {
4949
.navigationBarTitle(Text("Files in group"))
5050
}
5151

52-
func loadData() {
53-
self.api.uploadcare?.groupInfo(withUUID: self.viewData.group.id) { result in
54-
defer { self.isLoading = false }
52+
func loadData() async throws {
53+
defer {
54+
DispatchQueue.main.async {
55+
self.isLoading = false
56+
}
57+
}
5558

56-
switch result {
57-
case .failure(let error):
58-
self.alertMessage = error.detail
59-
self.isShowingAlert.toggle()
60-
DLog(error)
61-
case .success(let group):
59+
do {
60+
guard let group = try await self.api.uploadcare?.groupInfo(withUUID: self.viewData.group.id) else { return }
61+
DispatchQueue.main.async {
6262
self.filesListStore.files.removeAll()
6363
group.files?.forEach { self.filesListStore.files.append(FileViewData( file: $0)) }
6464
}
65+
} catch {
66+
DispatchQueue.main.async {
67+
self.alertMessage = (error as? RESTAPIError)?.detail ?? "Error"
68+
DLog(error)
69+
}
6570
}
66-
// filesListStore.uploadcare = self.api.uploadcare
67-
// filesListStore.load { (list, error) in
68-
// defer { self.isLoading = false }
69-
// if let error = error {
70-
// self.alertMessage = error.detail
71-
// self.isShowingAlert.toggle()
72-
// return print(error)
73-
// }
74-
// self.filesListStore.files.removeAll()
75-
// list?.results.forEach { self.filesListStore.files.append(FileViewData( file: $0)) }
76-
// }
7771
}
7872
}
7973

Demo/Demo/Views/GroupsList/GroupsListView.swift

+7-3
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ struct GroupsListView: View {
1919
GroupRowView(groupData: group)
2020
.onAppear {
2121
if group.group.id == viewModel.groups.last?.group.id {
22-
viewModel.loadMoreIfNeed()
22+
Task {
23+
try await viewModel.loadMoreIfNeed()
24+
}
2325
}
2426
}
2527
}
2628
}
2729
}
28-
}.onAppear { [self] in
29-
viewModel.loadData()
30+
}.onAppear {
31+
Task {
32+
try await viewModel.loadData()
33+
}
3034
}.navigationBarTitle(Text("List of groups"))
3135
}
3236
}

0 commit comments

Comments
 (0)