Skip to content

Instantly share code, notes, and snippets.

@pffan91
Last active February 7, 2019 12:46
Show Gist options
  • Save pffan91/b543dd9c2d5350af7a4e34b631c1bf1c to your computer and use it in GitHub Desktop.
Save pffan91/b543dd9c2d5350af7a4e34b631c1bf1c to your computer and use it in GitHub Desktop.
NetworkLayerWithMoya_fullExample
#1 Moya Target
import Foundation
import Moya
enum MyAPI {
// MARK: - User
case createUser(model: User)
case changePassword(currentPassword: String, newPassword: String)
case resetPasswordForEmail(email: String)
}
extension MyAPI: TargetType {
var baseURL: URL { return URL(string: "###SERVER_ADDRESS###")! }
var path: String {
switch self {
case .createUser:
return "/user"
case .resetPasswordForEmail:
return "/user/reset-password"
case .changePassword:
return "/user"
}
}
var method: Moya.Method {
switch self {
case .resetPasswordForEmail:
return .post
case .changePassword:
return .put
default:
return .get
}
}
var parameters: [String: Any]? {
switch self {
case .createUser(let model):
var parameters = [String: Any]()
parameters["name"] = model.name
parameters["company_name"] = model.companyName
parameters["email"] = model.email
parameters["plain_password"] = model.plainPassword
parameters["current_password"] = model.currentPassword
parameters["dealer_code"] = model.dealerCode
parameters["country_code"] = model.countryCode
parameters["phone"] = model.phone
return parameters
case .changePassword(let currentPassword, let newPassword):
var parameters = [String: Any]()
parameters["plain_password"] = newPassword
parameters["current_password"] = currentPassword
return parameters
case .resetPasswordForEmail(let email):
var parameters = [String: Any]()
parameters["email"] = email
return parameters
default:
return nil
}
}
var parameterEncoding: ParameterEncoding {
return JSONEncoding.default
}
var sampleData: Data {
return Data()
}
var task: Task {
return .request
}
/*var validate: Bool {
return true
}*/
}
#2 NetworkAdapter
import UIKit
import Moya
struct NetworkAdapterSigned {
static let provider = MyProvider() # custom provider to manage oAuth 2.0 authorization and token refreshing, in basic case here will be MoyaProvider<MyAPI>()
static func request(target: MyAPI, success successCallback: @escaping (Response) -> Void, error errorCallback: @escaping (MyHTTPRequestError) -> Void, failure failureCallback: @escaping (MoyaError) -> Void) { # MyHTTPRequestError is custom error class
provider.request(target) { (result) in
switch result {
case .success(let response):
do {
if response.statusCode >= 200 && response.statusCode <= 300 {
successCallback(response)
} else {
# parse error, create it and then send to errorCallback
errorCallback(resultError)
}
} catch {
# generate parsing error and send it to errorCallback
errorCallback(resultError)
}
case .failure(let error):
failureCallback(error)
}
}
}
}
#3 Worker
import UIKit
import PromiseKit
import Moya
import KeychainAccess
class UserWorker: NSObject {
class func register(registrationData: RegistrationData) -> Promise<User> {
return Promise { fulfill, reject in
let userModel = User(name: registrationData.name, companyName: registrationData.companyName, email: registrationData.email, plainPassword: registrationData.password, currentPassword: registrationData.confirmPassword, dealerCode: registrationData.dealerCode, countryCode: registrationData.countryCode, phone: registrationData.phoneNumber) # some kind of legacy code
NetworkAdapterUnsigned.request(target: .createUser(model: userModel), success: { ( respons ) in
let result: UserMapped = try response.mapObject() as UserMapped # parsing
fulfill(result)
}, error: { (error) in
let resultError = ErrorHelper.generateErrorFromMyHTTPRequestError(requestError: error)
reject(error)
}, failure: { (error) in
reject(error)
})
}
}
class func resetPassword(email: String) -> Promise<Void> {
return Promise { fulfill, reject in
NetworkAdapterUnsigned.request(target: .resetPassword(email: email), success: { _ in
fulfill()
}, error: { (error) in
let resultError = ErrorHelper.generateErrorFromMyHTTPRequestError(requestError: error)
reject(resultError)
}, failure: { (error) in
reject(error)
})
}
}
class func changePasswordPassword(currentPassword: String, newPassword: String) -> Promise<Void> {
return Promise { fulfill, reject in
NetworkAdapterSigned.request(target: .changePassword(currentPassword: currentPassword, newPassword: newPassword), success: { _ in
# save to Keychains
fulfill()
}, error: { (error) in
let resultError = ErrorHelper.generateErrorFromMyHTTPRequestError(requestError: error)
reject(resultError)
}, failure: { (error) in
reject(error)
})
}
}
}
#4 Model
import UIKit
import Mapper
class UserMapped: Mappable {
var name: String?
var email: String?
var uid: String?
# and other fields
required init(map: Mapper) throws {
try name = map.from("name")
try uid = map.from("uid")
email = map.optionalFrom("email") # optional parameter for example
}
}
#5 Call Worker's method in UIViewController (dont foget about import PromiseKit)
UserWorker.register(registrationData: viewModel.registrationData).then { user in
# do something with user object
print(user)
}.catch { error in
# show error
print(error)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment