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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
//
// Service.swift
// Juick
//
// Created by Vitaly Takmazov on 16.09.2020.
// Copyright © 2020 com.juick. All rights reserved.
//
import Foundation
class Service : NSObject, URLSessionDelegate, URLSessionTaskDelegate {
let backgroundQueue = OperationQueue()
let baseURL : URL?
lazy var authorizationHeader : String? = {
if let token = UserDefaults.standard.string(forKey: "token") {
return "Juick \(token)"
}
return nil;
}()
override init() {
let baseURLString = Bundle.main.object(forInfoDictionaryKey:"base_url") as! String
debugPrint("Initializing with \(baseURLString) base URL")
self.baseURL = URL(string: baseURLString)
super.init()
}
func url(url:URL, params:[String: String]) -> URL {
let parametersUrl = NSURLComponents(url: url, resolvingAgainstBaseURL: true)
var items : [URLQueryItem] = []
for (key, value) in params {
items.append(URLQueryItem(name: key, value: value))
}
parametersUrl?.queryItems = items
return (parametersUrl?.url!)!
}
func fetchData(url:URL, postData:Data?, boundary:String?, header:String?, callback: @escaping (Data?, Error?) -> Void) {
var request = URLRequest(url: url)
if (header != nil) {
request.addValue(header!, forHTTPHeaderField:"Authorization")
}
if (boundary != nil) {
request.httpMethod = "POST";
request.httpBody = postData;
let contentType = "multipart/form-data; boundary=\(boundary!)"
request.setValue(contentType, forHTTPHeaderField:"Content-Type")
} else if (postData != nil) {
request.httpMethod = "PUT";
request.httpBody = postData;
request.setValue("application/json", forHTTPHeaderField:"Content-Type")
} else {
request.httpMethod = "GET";
}
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
if (error != nil) {
OperationQueue.main.addOperation {
callback(nil, error)
}
} else {
let statusCode = (response as? HTTPURLResponse)?.statusCode ?? 457
if (response == nil || statusCode != 200) {
let url = request.url
let err = NSError(domain: "JuickErrorDomain", code: statusCode, userInfo: ["url":url!.absoluteString])
OperationQueue.main.addOperation {
callback(nil, err)
}
} else {
OperationQueue.main.addOperation {
callback(data, error)
}
}
}
})
self.backgroundQueue.addOperation {
task.resume()
}
}
private func multipartData(params:[String:String], boundary:String) -> Data {
var body = Data()
for (key, value) in params {
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\(key)\r\n\r\n".data(using: .utf8)!)
body.append("\(value)\r\n".data(using: .utf8)!)
}
body.append("--\(boundary)--".data(using: .utf8)!)
return body;
}
private func get(path:String, params:[String:String], callback:@escaping (NSDictionary?, Error?) -> Void) {
if let url = URL(string: path, relativeTo: self.baseURL) {
let requestUrl = params.isEmpty ? url : self.url(url: url, params: params)
fetchData(url: requestUrl, postData: nil, boundary: nil, header: self.authorizationHeader) {
(responseData, err) in
if (err != nil) {
callback(nil, err)
} else {
if let data = responseData, let jsonData = try? JSONSerialization.jsonObject(with: data, options: []) {
callback(jsonData as? NSDictionary, nil)
} else {
callback(nil, NSError(domain: "JuickErrorDomain", code: 500, userInfo: ["message":"JSON error"]))
}
}
}
}
}
func post(path: String, params:[String:String], callback:@escaping (NSDictionary?, Error?) -> Void) {
if let url = URL(string: path, relativeTo: self.baseURL) {
let boundary = "Boundary-\(UUID().uuidString)";
fetchData(url: url, postData:multipartData(params: params, boundary: boundary), boundary: boundary, header: self.authorizationHeader) {
(responseData, err) in
if (err != nil) {
callback(nil, err)
} else {
if let data = responseData, let jsonData = try? JSONSerialization.jsonObject(with: data, options: []) {
callback(jsonData as? NSDictionary, nil)
} else {
callback(nil, NSError(domain: "JuickErrorDomain", code: 500, userInfo: ["message":"JSON error"]))
}
}
}
}
}
func fetchImage(url:URL, callback:@escaping(Data?)-> Void) {
fetchData(url: url, postData: nil, boundary: nil, header: self.authorizationHeader) { (data, err) in
if (err != nil) {
callback(nil);
} else {
callback(data);
}
}
}
}
|