Skip to content
This repository was archived by the owner on Jan 28, 2019. It is now read-only.

Commit dc21b46

Browse files
author
Peter Zignego
committed
SwiftLint + gardening
1 parent 5f15ba6 commit dc21b46

File tree

5 files changed

+822
-314
lines changed

5 files changed

+822
-314
lines changed

.swiftlint.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
disabled_rules:
2+
- identifier_name
3+
- function_parameter_count
4+
line_length: 140
5+
excluded: # paths to ignore during linting. Takes precedence over `included`.
6+
- Carthage
7+
- Pods

SKWebAPI.xcodeproj/project.pbxproj

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
26A2E62B1EEB26C3005C25AC /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A2E62A1EEB26C3005C25AC /* Endpoint.swift */; };
11+
26A2E62C1EEB26C3005C25AC /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A2E62A1EEB26C3005C25AC /* Endpoint.swift */; };
12+
26A2E62D1EEB26C3005C25AC /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A2E62A1EEB26C3005C25AC /* Endpoint.swift */; };
1013
26D1C4C21EE462DC00C95954 /* SKCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26D1C4C11EE462DC00C95954 /* SKCore.framework */; };
1114
26D1C4C61EE463A600C95954 /* SKCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26D1C4C51EE463A600C95954 /* SKCore.framework */; };
1215
26D1C4C81EE463AD00C95954 /* SKCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26D1C4C71EE463AD00C95954 /* SKCore.framework */; };
@@ -23,6 +26,7 @@
2326
2684F1E41E95ABD400536DCC /* SKWebAPI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SKWebAPI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2427
2684F2081E95ABD600536DCC /* SKWebAPI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SKWebAPI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2528
2684F20D1E95AF8C00536DCC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
29+
26A2E62A1EEB26C3005C25AC /* Endpoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = "<group>"; };
2630
26D1C4C11EE462DC00C95954 /* SKCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SKCore.framework; path = Carthage/Build/Mac/SKCore.framework; sourceTree = "<group>"; };
2731
26D1C4C51EE463A600C95954 /* SKCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SKCore.framework; path = Carthage/Build/iOS/SKCore.framework; sourceTree = "<group>"; };
2832
26D1C4C71EE463AD00C95954 /* SKCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SKCore.framework; path = Carthage/Build/tvOS/SKCore.framework; sourceTree = "<group>"; };
@@ -110,6 +114,7 @@
110114
children = (
111115
26DC0EA51E95BB5D00991BDF /* NetworkInterface.swift */,
112116
26DC0EA61E95BB5D00991BDF /* WebAPI.swift */,
117+
26A2E62A1EEB26C3005C25AC /* Endpoint.swift */,
113118
);
114119
path = Sources;
115120
sourceTree = SOURCE_ROOT;
@@ -149,6 +154,7 @@
149154
2684F1791E95AA6900536DCC /* Frameworks */,
150155
2684F17A1E95AA6900536DCC /* Headers */,
151156
2684F17B1E95AA6900536DCC /* Resources */,
157+
26A2E62E1EEB27AB005C25AC /* SwiftLint */,
152158
);
153159
buildRules = (
154160
);
@@ -167,6 +173,7 @@
167173
2684F1DE1E95ABD400536DCC /* Frameworks */,
168174
2684F1DF1E95ABD400536DCC /* Headers */,
169175
2684F1E01E95ABD400536DCC /* Resources */,
176+
26A2E62F1EEB27CB005C25AC /* SwiftLint */,
170177
);
171178
buildRules = (
172179
);
@@ -185,6 +192,7 @@
185192
2684F2021E95ABD600536DCC /* Frameworks */,
186193
2684F2031E95ABD600536DCC /* Headers */,
187194
2684F2041E95ABD600536DCC /* Resources */,
195+
26A2E6301EEB27D8005C25AC /* SwiftLint */,
188196
);
189197
buildRules = (
190198
);
@@ -259,12 +267,58 @@
259267
};
260268
/* End PBXResourcesBuildPhase section */
261269

270+
/* Begin PBXShellScriptBuildPhase section */
271+
26A2E62E1EEB27AB005C25AC /* SwiftLint */ = {
272+
isa = PBXShellScriptBuildPhase;
273+
buildActionMask = 2147483647;
274+
files = (
275+
);
276+
inputPaths = (
277+
);
278+
name = SwiftLint;
279+
outputPaths = (
280+
);
281+
runOnlyForDeploymentPostprocessing = 0;
282+
shellPath = /bin/sh;
283+
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
284+
};
285+
26A2E62F1EEB27CB005C25AC /* SwiftLint */ = {
286+
isa = PBXShellScriptBuildPhase;
287+
buildActionMask = 2147483647;
288+
files = (
289+
);
290+
inputPaths = (
291+
);
292+
name = SwiftLint;
293+
outputPaths = (
294+
);
295+
runOnlyForDeploymentPostprocessing = 0;
296+
shellPath = /bin/sh;
297+
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
298+
};
299+
26A2E6301EEB27D8005C25AC /* SwiftLint */ = {
300+
isa = PBXShellScriptBuildPhase;
301+
buildActionMask = 2147483647;
302+
files = (
303+
);
304+
inputPaths = (
305+
);
306+
name = SwiftLint;
307+
outputPaths = (
308+
);
309+
runOnlyForDeploymentPostprocessing = 0;
310+
shellPath = /bin/sh;
311+
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
312+
};
313+
/* End PBXShellScriptBuildPhase section */
314+
262315
/* Begin PBXSourcesBuildPhase section */
263316
2684F1781E95AA6900536DCC /* Sources */ = {
264317
isa = PBXSourcesBuildPhase;
265318
buildActionMask = 2147483647;
266319
files = (
267320
26DC0EA71E95BB5D00991BDF /* NetworkInterface.swift in Sources */,
321+
26A2E62B1EEB26C3005C25AC /* Endpoint.swift in Sources */,
268322
26DC0EAA1E95BB5D00991BDF /* WebAPI.swift in Sources */,
269323
);
270324
runOnlyForDeploymentPostprocessing = 0;
@@ -274,6 +328,7 @@
274328
buildActionMask = 2147483647;
275329
files = (
276330
26DC0EA81E95BB5D00991BDF /* NetworkInterface.swift in Sources */,
331+
26A2E62C1EEB26C3005C25AC /* Endpoint.swift in Sources */,
277332
26DC0EAB1E95BB5D00991BDF /* WebAPI.swift in Sources */,
278333
);
279334
runOnlyForDeploymentPostprocessing = 0;
@@ -283,6 +338,7 @@
283338
buildActionMask = 2147483647;
284339
files = (
285340
26DC0EA91E95BB5D00991BDF /* NetworkInterface.swift in Sources */,
341+
26A2E62D1EEB26C3005C25AC /* Endpoint.swift in Sources */,
286342
26DC0EAC1E95BB5D00991BDF /* WebAPI.swift in Sources */,
287343
);
288344
runOnlyForDeploymentPostprocessing = 0;

Sources/Endpoint.swift

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//
2+
// WebAPI.swift
3+
//
4+
// Copyright © 2017 Peter Zignego. All rights reserved.
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in
14+
// all copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
// THE SOFTWARE.
23+
24+
public enum Endpoint: String {
25+
case apiTest = "api.test"
26+
case authRevoke = "auth.revoke"
27+
case authTest = "auth.test"
28+
case channelsHistory = "channels.history"
29+
case channelsInfo = "channels.info"
30+
case channelsList = "channels.list"
31+
case channelsMark = "channels.mark"
32+
case channelsSetPurpose = "channels.setPurpose"
33+
case channelsSetTopic = "channels.setTopic"
34+
case chatDelete = "chat.delete"
35+
case chatPostMessage = "chat.postMessage"
36+
case chatMeMessage = "chat.meMessage"
37+
case chatUpdate = "chat.update"
38+
case dndInfo = "dnd.info"
39+
case dndTeamInfo = "dnd.teamInfo"
40+
case emojiList = "emoji.list"
41+
case filesCommentsAdd = "files.comments.add"
42+
case filesCommentsEdit = "files.comments.edit"
43+
case filesCommentsDelete = "files.comments.delete"
44+
case filesDelete = "files.delete"
45+
case filesInfo = "files.info"
46+
case filesUpload = "files.upload"
47+
case groupsClose = "groups.close"
48+
case groupsHistory = "groups.history"
49+
case groupsInfo = "groups.info"
50+
case groupsList = "groups.list"
51+
case groupsMark = "groups.mark"
52+
case groupsOpen = "groups.open"
53+
case groupsSetPurpose = "groups.setPurpose"
54+
case groupsSetTopic = "groups.setTopic"
55+
case imClose = "im.close"
56+
case imHistory = "im.history"
57+
case imList = "im.list"
58+
case imMark = "im.mark"
59+
case imOpen = "im.open"
60+
case mpimClose = "mpim.close"
61+
case mpimHistory = "mpim.history"
62+
case mpimList = "mpim.list"
63+
case mpimMark = "mpim.mark"
64+
case mpimOpen = "mpim.open"
65+
case oauthAccess = "oauth.access"
66+
case pinsAdd = "pins.add"
67+
case pinsRemove = "pins.remove"
68+
case reactionsAdd = "reactions.add"
69+
case reactionsGet = "reactions.get"
70+
case reactionsList = "reactions.list"
71+
case reactionsRemove = "reactions.remove"
72+
case rtmStart = "rtm.start"
73+
case starsAdd = "stars.add"
74+
case starsRemove = "stars.remove"
75+
case teamInfo = "team.info"
76+
case usersGetPresence = "users.getPresence"
77+
case usersInfo = "users.info"
78+
case usersList = "users.list"
79+
case usersSetActive = "users.setActive"
80+
case usersSetPresence = "users.setPresence"
81+
}

Sources/NetworkInterface.swift

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,24 @@
2222
// THE SOFTWARE.
2323

2424
#if os(Linux)
25-
import Dispatch
25+
import Dispatch
2626
#endif
2727
import Foundation
2828
import SKCore
2929

3030
public struct NetworkInterface {
31-
31+
3232
private let apiUrl = "https://slack.com/api/"
3333
private let session = URLSession(configuration: .default)
34-
34+
3535
internal init() {}
36-
37-
internal func request(_ endpoint: Endpoint, parameters: [String: Any?], successClosure: @escaping ([String: Any])->Void, errorClosure: @escaping (SlackError)->Void) {
36+
37+
internal func request(
38+
_ endpoint: Endpoint,
39+
parameters: [String: Any?],
40+
successClosure: @escaping ([String: Any]) -> Void,
41+
errorClosure: @escaping (SlackError) -> Void
42+
) {
3843
var components = URLComponents(string: "\(apiUrl)\(endpoint.rawValue)")
3944
if parameters.count > 0 {
4045
components?.queryItems = filterNilParameters(parameters).map { URLQueryItem(name: $0.0, value: "\($0.1)") }
@@ -44,7 +49,7 @@ public struct NetworkInterface {
4449
return
4550
}
4651
let request = URLRequest(url: url)
47-
52+
4853
session.dataTask(with: request) {(data, response, publicError) in
4954
do {
5055
successClosure(try NetworkInterface.handleResponse(data, response: response, publicError: publicError))
@@ -53,7 +58,7 @@ public struct NetworkInterface {
5358
}
5459
}.resume()
5560
}
56-
61+
5762
//Adapted from https://gist.github.com/erica/baa8a187a5b4796dab27
5863
internal func synchronusRequest(_ endpoint: Endpoint, parameters: [String: Any?]) -> [String: Any]? {
5964
var components = URLComponents(string: "\(apiUrl)\(endpoint.rawValue)")
@@ -78,8 +83,13 @@ public struct NetworkInterface {
7883
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
7984
return try? NetworkInterface.handleResponse(data, response: response, publicError: error)
8085
}
81-
82-
internal func customRequest(_ url: String, data: Data, success: @escaping (Bool)->Void, errorClosure: @escaping (SlackError)->Void) {
86+
87+
internal func customRequest(
88+
_ url: String,
89+
data: Data,
90+
success: @escaping (Bool) -> Void,
91+
errorClosure: @escaping (SlackError) -> Void
92+
) {
8393
guard let string = url.removingPercentEncoding, let url = URL(string: string) else {
8494
errorClosure(SlackError.clientNetworkError)
8595
return
@@ -89,22 +99,30 @@ public struct NetworkInterface {
8999
let contentType = "application/json"
90100
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
91101
request.httpBody = data
92-
93-
session.dataTask(with: request) {(data, response, publicError) in
102+
103+
session.dataTask(with: request) {(_, _, publicError) in
94104
if publicError == nil {
95105
success(true)
96106
} else {
97107
errorClosure(SlackError.clientNetworkError)
98108
}
99109
}.resume()
100110
}
101-
102-
internal func uploadRequest(data: Data, parameters: [String: Any?], successClosure: @escaping ([String: Any])->Void, errorClosure: @escaping (SlackError)->Void) {
111+
112+
internal func uploadRequest(
113+
data: Data,
114+
parameters: [String: Any?],
115+
successClosure: @escaping ([String: Any]) -> Void, errorClosure: @escaping (SlackError) -> Void
116+
) {
103117
var components = URLComponents(string: "\(apiUrl)\(Endpoint.filesUpload.rawValue)")
104118
if parameters.count > 0 {
105119
components?.queryItems = filterNilParameters(parameters).map { URLQueryItem(name: $0.0, value: "\($0.1)") }
106120
}
107-
guard let url = components?.url, let filename = parameters["filename"] as? String, let filetype = parameters["filetype"] as? String else {
121+
guard
122+
let url = components?.url,
123+
let filename = parameters["filename"] as? String,
124+
let filetype = parameters["filetype"] as? String
125+
else {
108126
errorClosure(SlackError.clientNetworkError)
109127
return
110128
}
@@ -116,22 +134,27 @@ public struct NetworkInterface {
116134
let boundaryEnd = "--\(boundaryConstant)--\r\n"
117135
let contentDispositionString = "Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n"
118136
let contentTypeString = "Content-Type: \(filetype)\r\n\r\n"
119-
120-
guard let boundaryStartData = boundaryStart.data(using: .utf8), let dispositionData = contentDispositionString.data(using: .utf8), let contentTypeData = contentTypeString.data(using: .utf8), let boundaryEndData = boundaryEnd.data(using: .utf8) else {
137+
138+
guard
139+
let boundaryStartData = boundaryStart.data(using: .utf8),
140+
let dispositionData = contentDispositionString.data(using: .utf8),
141+
let contentTypeData = contentTypeString.data(using: .utf8),
142+
let boundaryEndData = boundaryEnd.data(using: .utf8)
143+
else {
121144
errorClosure(SlackError.clientNetworkError)
122145
return
123146
}
124-
147+
125148
var requestBodyData = Data()
126149
requestBodyData.append(contentsOf: boundaryStartData)
127150
requestBodyData.append(contentsOf: dispositionData)
128151
requestBodyData.append(contentsOf: contentTypeData)
129152
requestBodyData.append(contentsOf: data)
130153
requestBodyData.append(contentsOf: boundaryEndData)
131-
154+
132155
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
133156
request.httpBody = requestBodyData as Data
134-
157+
135158
session.dataTask(with: request) {(data, response, publicError) in
136159
do {
137160
successClosure(try NetworkInterface.handleResponse(data, response: response, publicError: publicError))
@@ -140,7 +163,7 @@ public struct NetworkInterface {
140163
}
141164
}.resume()
142165
}
143-
166+
144167
internal static func handleResponse(_ data: Data?, response: URLResponse?, publicError: Error?) throws -> [String: Any] {
145168
guard let data = data, let response = response as? HTTPURLResponse else {
146169
throw SlackError.clientNetworkError
@@ -149,10 +172,10 @@ public struct NetworkInterface {
149172
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
150173
throw SlackError.clientJSONError
151174
}
152-
175+
153176
switch response.statusCode {
154177
case 200:
155-
if (json["ok"] as! Bool == true) {
178+
if json["ok"] as? Bool == true {
156179
return json
157180
} else {
158181
if let errorString = json["error"] as? String {
@@ -174,16 +197,16 @@ public struct NetworkInterface {
174197
}
175198
}
176199
}
177-
200+
178201
private func randomBoundary() -> String {
179202
#if os(Linux)
180203
return "slackkit.boundary.\(Int(random()))\(Int(random()))"
181204
#else
182205
return "slackkit.boundary.\(arc4random())\(arc4random())"
183206
#endif
184207
}
185-
186-
//MARK: - Filter Nil Parameters
208+
209+
// MARK: - Filter Nil Parameters
187210
private func filterNilParameters(_ parameters: [String: Any?]) -> [String: Any] {
188211
var finalParameters = [String: Any]()
189212
for (key, value) in parameters {

0 commit comments

Comments
 (0)