feat: add MastodonAPI
This commit is contained in:
parent
19ddb106ad
commit
3d5afbd589
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
3533495136D843E85211E3E2 /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1B4523A7981F1044DE89C21 /* Pods_Mastodon_MastodonUITests.framework */; };
|
3533495136D843E85211E3E2 /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1B4523A7981F1044DE89C21 /* Pods_Mastodon_MastodonUITests.framework */; };
|
||||||
|
5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 5D526FE125BE9AC400460CB9 /* MastodonSDK */; };
|
||||||
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
|
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
|
||||||
7A9135D4559750AF07CA9BE4 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 602D783BEC22881EBAD84419 /* Pods_Mastodon.framework */; };
|
7A9135D4559750AF07CA9BE4 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 602D783BEC22881EBAD84419 /* Pods_Mastodon.framework */; };
|
||||||
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB3D0FF225BAA61700EAA174 /* AlamofireImage */; };
|
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB3D0FF225BAA61700EAA174 /* AlamofireImage */; };
|
||||||
|
@ -76,6 +77,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */,
|
||||||
7A9135D4559750AF07CA9BE4 /* Pods_Mastodon.framework in Frameworks */,
|
7A9135D4559750AF07CA9BE4 /* Pods_Mastodon.framework in Frameworks */,
|
||||||
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */,
|
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */,
|
||||||
);
|
);
|
||||||
|
@ -226,6 +228,7 @@
|
||||||
name = Mastodon;
|
name = Mastodon;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
DB3D0FF225BAA61700EAA174 /* AlamofireImage */,
|
DB3D0FF225BAA61700EAA174 /* AlamofireImage */,
|
||||||
|
5D526FE125BE9AC400460CB9 /* MastodonSDK */,
|
||||||
);
|
);
|
||||||
productName = Mastodon;
|
productName = Mastodon;
|
||||||
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
|
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
|
||||||
|
@ -830,6 +833,10 @@
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
5D526FE125BE9AC400460CB9 /* MastodonSDK */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = MastodonSDK;
|
||||||
|
};
|
||||||
DB3D0FF225BAA61700EAA174 /* AlamofireImage */ = {
|
DB3D0FF225BAA61700EAA174 /* AlamofireImage */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
|
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
|
||||||
|
|
|
@ -18,6 +18,33 @@
|
||||||
"revision": "3e8edbeb75227f8542aa87f90240cf0424d6362f",
|
"revision": "3e8edbeb75227f8542aa87f90240cf0424d6362f",
|
||||||
"version": "4.1.0"
|
"version": "4.1.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "swift-nio",
|
||||||
|
"repositoryURL": "https://github.com/apple/swift-nio.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "8da5c5a4e6c5084c296b9f39dc54f00be146e0fa",
|
||||||
|
"version": "1.14.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "swift-nio-zlib-support",
|
||||||
|
"repositoryURL": "https://github.com/apple/swift-nio-zlib-support.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "37760e9a52030bb9011972c5213c3350fa9d41fd",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "SwiftyJSON",
|
||||||
|
"repositoryURL": "https://github.com/SwiftyJSON/SwiftyJSON.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "2b6054efa051565954e1d2b9da831680026cd768",
|
||||||
|
"version": "5.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import MastodonSDK
|
||||||
|
|
||||||
class ViewController: UIViewController {
|
class ViewController: UIViewController {
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
// Do any additional setup after loading the view.
|
// Do any additional setup after loading the view.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,18 @@ let package = Package(
|
||||||
targets: ["MastodonSDK"]),
|
targets: ["MastodonSDK"]),
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
// Dependencies declare other packages that this package depends on.
|
.package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "5.0.0"),
|
||||||
// .package(url: /* package url */, from: "1.0.0"),
|
.package(url: "https://github.com/apple/swift-nio.git", from: "1.0.0"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||||
.target(
|
.target(
|
||||||
name: "MastodonSDK",
|
name: "MastodonSDK",
|
||||||
dependencies: []
|
dependencies: [
|
||||||
|
.product(name: "SwiftyJSON", package: "SwiftyJSON"),
|
||||||
|
.product(name: "NIOHTTP1", package: "swift-nio"),
|
||||||
|
]
|
||||||
),
|
),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "MastodonSDKTests",
|
name: "MastodonSDKTests",
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// Mastodon+API+App.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by xiaojian sun on 2021/1/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension Mastodon.API.App {
|
||||||
|
internal static let appEndpointURL = Mastodon.API.endpointURL.appendingPathComponent("apps")
|
||||||
|
|
||||||
|
struct OAuth2Credentials: Codable {
|
||||||
|
public let id: String
|
||||||
|
|
||||||
|
public let name: String
|
||||||
|
public let website: String?
|
||||||
|
public let redirectURI: String
|
||||||
|
public let clientID: String
|
||||||
|
public let clientSecret: String
|
||||||
|
public let vapidKey: String
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
|
|
||||||
|
case name
|
||||||
|
case website
|
||||||
|
case redirectURI = "redirect_uri"
|
||||||
|
case clientID = "client_id"
|
||||||
|
case clientSecret = "client_secret"
|
||||||
|
case vapidKey = "vapid_key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct registerAppQuery {
|
||||||
|
public let client_name: String
|
||||||
|
public let redirect_uris: String
|
||||||
|
public let scopes: String
|
||||||
|
public let website: String
|
||||||
|
|
||||||
|
public init(client_name: String, redirect_uris: String, scopes: String, website: String) {
|
||||||
|
self.client_name = client_name
|
||||||
|
self.redirect_uris = redirect_uris
|
||||||
|
self.scopes = scopes
|
||||||
|
self.website = website
|
||||||
|
}
|
||||||
|
|
||||||
|
var queryItems: [URLQueryItem]? {
|
||||||
|
var items: [URLQueryItem] = []
|
||||||
|
items.append(URLQueryItem(name: "client_name", value: client_name))
|
||||||
|
items.append(URLQueryItem(name: "redirect_uris", value: redirect_uris))
|
||||||
|
items.append(URLQueryItem(name: "scopes", value: scopes))
|
||||||
|
guard !items.isEmpty else { return nil }
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Mastodon.API.App.OAuth2Credentials: Equatable {}
|
|
@ -0,0 +1,73 @@
|
||||||
|
//
|
||||||
|
// Mastodon+API.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by xiaojian sun on 2021/1/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import NIOHTTP1
|
||||||
|
|
||||||
|
public extension Mastodon.API {
|
||||||
|
static var baseUrl = ""
|
||||||
|
static let endpointURL = URL(string: baseUrl + "/api/v1/")!
|
||||||
|
|
||||||
|
static let timeoutInterval: TimeInterval = 10
|
||||||
|
static let decoder: JSONDecoder = {
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
decoder.dateDecodingStrategy = .MastodonStrategy
|
||||||
|
return decoder
|
||||||
|
}()
|
||||||
|
|
||||||
|
static let httpHeaderDateFormatter: DateFormatter = {
|
||||||
|
let formatter = DateFormatter()
|
||||||
|
formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
|
||||||
|
return formatter
|
||||||
|
}()
|
||||||
|
|
||||||
|
enum App {}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Mastodon.API {
|
||||||
|
// Error Response when request V1 endpoint
|
||||||
|
struct ErrorResponse: Codable {
|
||||||
|
let errors: [ErrorDescription]
|
||||||
|
|
||||||
|
struct ErrorDescription: Codable {
|
||||||
|
public let code: Int
|
||||||
|
public let message: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alternative Error Response when request V1 endpoint
|
||||||
|
struct ErrorRequestResponse: Codable {
|
||||||
|
let request: String
|
||||||
|
let error: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Mastodon.API {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension JSONDecoder.DateDecodingStrategy {
|
||||||
|
static let MastodonStrategy = custom { decoder throws -> Date in
|
||||||
|
let container = try decoder.singleValueContainer()
|
||||||
|
let string = try container.decode(String.self)
|
||||||
|
|
||||||
|
let formatterV1 = DateFormatter()
|
||||||
|
formatterV1.locale = Locale(identifier: "en")
|
||||||
|
formatterV1.dateFormat = "EEE MMM dd HH:mm:ss ZZZZZ yyyy"
|
||||||
|
if let date = formatterV1.date(from: string) {
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
|
||||||
|
let formatterV2 = ISO8601DateFormatter()
|
||||||
|
formatterV2.formatOptions.insert(.withFractionalSeconds)
|
||||||
|
if let date = formatterV2.date(from: string) {
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
|
||||||
|
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: \(string)")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
//
|
||||||
|
// File.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by xiaojian sun on 2021/1/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
extension Mastodon.Entity { }
|
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// File.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by xiaojian sun on 2021/1/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public enum Mastodon {
|
||||||
|
public enum Request { }
|
||||||
|
public enum Response { }
|
||||||
|
public enum API { }
|
||||||
|
public enum Entity { }
|
||||||
|
}
|
|
@ -1,3 +1 @@
|
||||||
struct MastodonSDK {
|
|
||||||
var text = "Hello, World!"
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue