-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathWordPressOrgRestApi.swift
105 lines (90 loc) · 4.13 KB
/
WordPressOrgRestApi.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import Alamofire
import Foundation
/**
Error constants for the WordPress.org REST API
- RequestSerializationFailed: The serialization of the request failed
*/
@objc public enum WordPressOrgRestApiError: Int, Error {
case requestSerializationFailed
}
@objc
open class WordPressOrgRestApi: NSObject, WordPressRestApi {
public typealias Completion = (Swift.Result<Any, Error>, HTTPURLResponse?) -> Void
private let apiBase: URL
private let authenticator: Authenticator?
private let userAgent: String?
public init(apiBase: URL, authenticator: Authenticator? = nil, userAgent: String? = nil) {
self.apiBase = apiBase
self.authenticator = authenticator
self.userAgent = userAgent
super.init()
}
@discardableResult
open func GET(_ path: String,
parameters: [String: AnyObject]?,
completion: @escaping Completion) -> Progress? {
return request(method: .get, path: path, parameters: parameters, completion: completion)
}
@discardableResult
open func POST(_ path: String,
parameters: [String: AnyObject]?,
completion: @escaping Completion) -> Progress? {
return request(method: .post, path: path, parameters: parameters, completion: completion)
}
@discardableResult
open func request(method: HTTPMethod,
path: String,
parameters: [String: AnyObject]?,
completion: @escaping Completion) -> Progress? {
let relativePath = path.removingPrefix("/")
guard let url = URL(string: relativePath, relativeTo: apiBase) else {
let error = NSError(domain: String(describing: WordPressOrgRestApiError.self),
code: WordPressOrgRestApiError.requestSerializationFailed.rawValue,
userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Failed to serialize request to the REST API.", comment: "Error message to show when wrong URL format is used to access the REST API")])
completion(.failure(error), nil)
return nil
}
let progress = Progress(totalUnitCount: 1)
let progressUpdater = {(taskProgress: Progress) in
progress.totalUnitCount = taskProgress.totalUnitCount
progress.completedUnitCount = taskProgress.completedUnitCount
}
let dataRequest = sessionManager.request(url, method: method, parameters: parameters, encoding: URLEncoding.default)
.validate()
.responseJSON(completionHandler: { (response) in
switch response.result {
case .success(let responseObject):
progress.completedUnitCount = progress.totalUnitCount
completion(.success(responseObject), response.response)
case .failure(let error):
completion(.failure(error), response.response)
}
}).downloadProgress(closure: progressUpdater)
progress.cancellationHandler = {
dataRequest.cancel()
}
return progress
}
/**
Cancels all ongoing and makes the session so the object will not fullfil any more request
*/
@objc open func invalidateAndCancelTasks() {
sessionManager.session.invalidateAndCancel()
}
private lazy var sessionManager: Alamofire.SessionManager = {
let sessionConfiguration = URLSessionConfiguration.default
let sessionManager = self.makeSessionManager(configuration: sessionConfiguration)
return sessionManager
}()
private func makeSessionManager(configuration sessionConfiguration: URLSessionConfiguration) -> Alamofire.SessionManager {
var additionalHeaders: [String: AnyObject] = [:]
if let userAgent = self.userAgent {
additionalHeaders["User-Agent"] = userAgent as AnyObject?
}
sessionConfiguration.httpAdditionalHeaders = additionalHeaders
let sessionManager = Alamofire.SessionManager(configuration: sessionConfiguration)
sessionManager.adapter = authenticator
sessionManager.retrier = authenticator
return sessionManager
}
}