Last active
February 7, 2019 12:46
-
-
Save pffan91/b543dd9c2d5350af7a4e34b631c1bf1c to your computer and use it in GitHub Desktop.
NetworkLayerWithMoya_fullExample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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