Skip to content

Commit 04eb3d5

Browse files
committed
Merge branch release/0.9.0
2 parents f4aadf6 + b580045 commit 04eb3d5

29 files changed

Lines changed: 519 additions & 277 deletions

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ let package = Package(
1414
dependencies: [
1515
.package(
1616
url: "https://github.com/Alamofire/Alamofire.git",
17-
from: "5.6.2"
17+
.upToNextMajor(from: "5.0.0")
1818
),
1919
],
2020
targets: [

RaAPIWrapper.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Pod::Spec.new do |s|
55

66
s.name = 'RaAPIWrapper'
77

8-
s.version = '0.8.3'
8+
s.version = '0.9.0'
99

1010
s.summary = 'Wrappers for requesting api.'
1111

@@ -27,7 +27,7 @@ Pod::Spec.new do |s|
2727

2828
s.module_name = 'APIWrapper'
2929

30-
s.source_files = 'Sources/*/*'
30+
s.source_files = 'Sources/*/**/*'
3131

3232
s.dependency 'Alamofire'
3333

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// APIHTTPMethod.swift
3+
// RaAPIWrapper
4+
//
5+
// Created by Rakuyo on 2022/12/15.
6+
// Copyright © 2022 Rakuyo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// The HTTP method to use when requesting the api.
12+
///
13+
/// With the `ExpressibleByStringLiteral` protocol,
14+
/// you can initialize the object directly with string literals
15+
public struct APIHTTPMethod: RawRepresentable {
16+
public typealias RawValue = String
17+
18+
public var rawValue: RawValue
19+
20+
public init(rawValue: RawValue) {
21+
self.rawValue = rawValue
22+
}
23+
}
24+
25+
// MARK: - ExpressibleByStringLiteral
26+
27+
extension APIHTTPMethod: ExpressibleByStringLiteral {
28+
public init(stringLiteral value: RawValue) {
29+
self.init(rawValue: value)
30+
}
31+
}
32+
33+
// MARK: - Hashable
34+
35+
extension APIHTTPMethod: Hashable { }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//
2+
// APIHeaders.swift
3+
// RaAPIWrapper
4+
//
5+
// Created by Rakuyo on 2022/12/15.
6+
// Copyright © 2022 Rakuyo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// Defines the type of header you can pass into the `API` property wrapper.
12+
public typealias APIHeaders = [String: String]

Sources/RequestInfo/APIInfoProtocol.swift

Lines changed: 0 additions & 40 deletions
This file was deleted.

Sources/RequestInfo/APIParameter.swift

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,55 +10,56 @@ import Foundation
1010

1111
public protocol APIParameter {
1212
/// Converts the target to an Encodable-compliant type.
13-
var toParameters: Encodable { get }
13+
var toParameters: AnyAPIHashableParameter { get }
1414
}
1515

1616
// MARK: - Default
1717

18-
extension APIParameter where Self: Encodable {
19-
public var toParameters: Encodable { self }
18+
extension APIParameter where Self: APIHashableParameter {
19+
public var toParameters: AnyAPIHashableParameter { .init(self) }
2020
}
2121

2222
// MARK: - Array
2323

2424
extension Array: APIParameter {
25-
public var toParameters: Encodable {
26-
(self as [Any?])
27-
.lazy
25+
public var toParameters: AnyAPIHashableParameter {
26+
let result: [AnyAPIHashableParameter] = (self as [Any?])
2827
.compactMap {
29-
if let value = $0 as? Encodable { return value }
28+
if let value = $0 as? (any APIHashableParameter) { return .init(value) }
3029
if let value = $0 as? APIParameter { return value.toParameters }
3130
return mapAnyObjectToEncodable($0 as? AnyObject)
3231
}
33-
.map { AnyEncodable($0) }
32+
33+
return .init(result)
3434
}
3535
}
3636

3737
// MARK: - Dictionary
3838

3939
extension Dictionary: APIParameter where Key == String {
40-
public var toParameters: Encodable {
41-
(self as [String: Any?])
40+
public var toParameters: AnyAPIHashableParameter {
41+
let result: [String: AnyAPIHashableParameter] = (self as [String: Any?])
4242
.compactMapValues {
43-
if let value = $0 as? Encodable { return value }
43+
if let value = $0 as? (any APIHashableParameter) { return .init(value) }
4444
if let value = $0 as? APIParameter { return value.toParameters }
4545
return mapAnyObjectToEncodable($0 as? AnyObject)
4646
}
47-
.mapValues { AnyEncodable($0) }
47+
48+
return .init(result)
4849
}
4950
}
5051

5152
// MARK: - Tools
5253

5354
fileprivate extension APIParameter {
54-
func mapAnyObjectToEncodable(_ value: AnyObject?) -> Encodable? {
55+
func mapAnyObjectToEncodable(_ value: AnyObject?) -> AnyAPIHashableParameter? {
5556
guard let _value = value else { return nil }
5657

57-
if let result = _value as? String { return result }
58-
if let result = _value as? Int { return result }
59-
if let result = _value as? Double { return result }
60-
if let result = _value as? Bool { return result }
61-
if let result = _value as? Data { return result }
58+
if let result = _value as? String { return .init(result) }
59+
if let result = _value as? Int { return .init(result) }
60+
if let result = _value as? Double { return .init(result) }
61+
if let result = _value as? Bool { return .init(result) }
62+
if let result = _value as? Data { return .init(result) }
6263
if let result = _value as? [String: Any] { return result.toParameters }
6364
if let result = _value as? [Any] { return result.toParameters }
6465

Sources/RequestInfo/APIRequestInfo.swift

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010

1111
/// Information needed to request the api
12-
open class APIRequestInfo: APIInfoProtocol {
12+
public struct APIRequestInfo {
1313
/// The path to the requested api
1414
public let path: String
1515

@@ -19,50 +19,39 @@ open class APIRequestInfo: APIInfoProtocol {
1919
public let specialBaseURL: URL?
2020

2121
/// Type representing HTTP methods
22-
public let method: APIHTTPMethod
22+
public let httpMethod: APIHTTPMethod
2323

2424
/// API header
2525
public let header: APIHeaders?
2626

2727
/// Parameters of the requested api
28-
public let parameters: APIParameters?
28+
public let parameters: AnyAPIHashableParameter?
2929

3030
/// Encoding of `parameters`
31-
public let parameterEncoding: APIParameterEncoding?
31+
public let parameterEncoding: AnyAPIHashableParameterEncoding?
32+
33+
///
34+
public let userInfo: APIRequestUserInfo
3235

3336
public init(
3437
path: String,
35-
specialBaseURL: URL?,
36-
method: APIHTTPMethod,
37-
header: APIHeaders?,
38-
parameters: APIParameters?,
39-
parameterEncoding: APIParameterEncoding?
38+
specialBaseURL: URL? = nil,
39+
httpMethod: APIHTTPMethod,
40+
header: APIHeaders? = nil,
41+
parameters: AnyAPIHashableParameter? = nil,
42+
parameterEncoding: AnyAPIHashableParameterEncoding? = nil,
43+
userInfo: APIRequestUserInfo = [:]
4044
) {
4145
self.path = path
4246
self.specialBaseURL = specialBaseURL
43-
self.method = method
47+
self.httpMethod = httpMethod
4448
self.header = header
4549
self.parameters = parameters
4650
self.parameterEncoding = parameterEncoding
51+
self.userInfo = userInfo
4752
}
4853
}
4954

5055
// MARK: - Hashable
5156

52-
extension APIRequestInfo: Hashable {
53-
public static func == (lhs: APIRequestInfo, rhs: APIRequestInfo) -> Bool {
54-
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
55-
}
56-
57-
public func hash(into hasher: inout Hasher) {
58-
hasher.combine(ObjectIdentifier(self))
59-
}
60-
}
61-
62-
// MARK: - CustomStringConvertible
63-
64-
extension APIRequestInfo: CustomStringConvertible {
65-
public var description: String {
66-
"specialBaseURL: \(specialBaseURL?.absoluteString ?? "nil"); path: \(path); method: \(method.rawValue); header: \(header?.description ?? "nil"); parameters: \(String(describing: parameters)); parameterEncoding: \(String(describing: parameterEncoding))"
67-
}
68-
}
57+
extension APIRequestInfo: Hashable { }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//
2+
// APIRequestUserInfo.swift
3+
// RaAPIWrapper
4+
//
5+
// Created by Rakuyo on 2022/8/25.
6+
// Copyright © 2022 Rakuyo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// Defines the type of custom data you can pass into the `API` property wrapper.
12+
public typealias APIRequestUserInfo = [AnyHashable: AnyHashable]
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
// AnyAPIHashable.swift
3+
// RaAPIWrapper
4+
//
5+
// Created by Rakuyo on 2022/12/15.
6+
// Copyright © 2022 Rakuyo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// You can make any property or protocol follow the `Hashable` protocol through this protocol.
12+
///
13+
/// Define a type, then make it follow the `AnyAPIHashable` protocol,
14+
/// then specify the type of Value as the type you want to make it follow the Hashable.
15+
/// That's all you need to do to get the job done.
16+
///
17+
/// See `AnyAPIHashableParameter` or `AnyAPIHashableParameterEncoding` for details on how to use it.
18+
/// the former makes the `Encodable` protocol follow `Hashable`,
19+
/// the latter makes `Alamofire.ParameterEncoding` do the same thing.
20+
public protocol AnyAPIHashable: Hashable, CustomStringConvertible, CustomDebugStringConvertible {
21+
/// The type itself that you want to make follow the Hashable protocol.
22+
/// For example: `typealias Value = Encodable`
23+
associatedtype Value
24+
25+
/// Storing the original object.
26+
var value: Value { get }
27+
28+
/// Used to implement `Equatable`.
29+
///
30+
/// When using this type, you do not need to care about the specifics of the value.
31+
var equals: (Value) -> Bool { get }
32+
33+
/// Used to implement `Hashable`.
34+
///
35+
/// When using this type, you do not need to care about the specifics of the value.
36+
var hash: (_ hasher: inout Hasher) -> Void { get }
37+
}
38+
39+
// MARK: - Hashable
40+
41+
extension AnyAPIHashable {
42+
public static func == (lhs: Self, rhs: Self) -> Bool {
43+
return lhs.equals(rhs.value)
44+
}
45+
46+
public func hash(into hasher: inout Hasher) {
47+
self.hash(&hasher)
48+
}
49+
}
50+
51+
// MARK: - CustomStringConvertible
52+
53+
extension AnyAPIHashable {
54+
public var description: String {
55+
// When printing the logs, only the objects that need attention are kept by themselves.
56+
.init(describing: value)
57+
}
58+
}
59+
60+
// MARK: - CustomDebugStringConvertible
61+
62+
extension AnyAPIHashable {
63+
public var debugDescription: String {
64+
// In debug mode, focus on the full content
65+
.init(describing: self)
66+
}
67+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// AnyAPIHashableParameter.swift
3+
// RaAPIWrapper
4+
//
5+
// Created by Rakuyo on 2022/12/15.
6+
// Copyright © 2022 Rakuyo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// API parameters.
12+
public typealias APIHashableParameter = AnyAPIHashableParameter.Input
13+
14+
/// Make `Encodable` follow `Hashable` protocol.
15+
public struct AnyAPIHashableParameter: AnyAPIHashable {
16+
public typealias Value = Encodable
17+
18+
public typealias Input = Value & Hashable
19+
20+
public let value: Value
21+
22+
public let equals: (Value) -> Bool
23+
24+
public let hash: (_ hasher: inout Hasher) -> Void
25+
26+
public init<T: Input>(_ value: T) {
27+
self.value = value
28+
self.equals = { ($0 as? T == value) }
29+
self.hash = { $0.combine(value) }
30+
}
31+
}
32+
33+
// MARK: - Encodable
34+
35+
extension AnyAPIHashableParameter: Encodable {
36+
public func encode(to encoder: Encoder) throws {
37+
try value.encode(to: encoder)
38+
}
39+
}

0 commit comments

Comments
 (0)