Chain call: return the object and then call the corresponding object method can be achieved

A case in point

Example a

Piggy. M -(Piggy *)buy_wood{NSLog(@" buy wood "); return self; / / here is critical thinking} - (Piggy *) build_A_House {NSLog (@ "house"); return self; // The idea here is crucial}Copy the code

implementation

Piggy * pig = [[[Piggy new] buy_wood] build_A_House]; To build houses and buy woodCopy the code

It’s a little tricky for us to use, and it’s unsightly, right? Of course there is a better way

Example 2

Piggy. M - (Piggy * (^) (void)) buy_wood {NSLog (@ "buy wood"); return ^{ return self; }; } - (Piggy * (^) (void)) build_A_House {NSLog (@ "house"); return ^{ return self; }; }Copy the code

implementation

Piggy *pig = [Piggy new]; pig.buy_wood().build_A_House(); To build houses and buy woodCopy the code

What do you say? It’s inside, right? What if you add parameters

Example 3

- (Piggy *(^)(NSString *))buy_wood{return ^(NSString *content){NSLog(@" buy wood at %@ ", content); return self; }; } - (Piggy *(^)(NSString *))build_A_House{return ^(NSString * content){NSLog(@" build a house at %@ ", content); return self; }; }Copy the code

implementation

Pig.buy_wood (@" Shanghai ").build_a_house (@" Beihai "); Exports in Shanghai to buy wood to build houses in BeihaiCopy the code

From this we can see, piggy is really small stupid pig 🐷. , of course, we still can observe, by using the method of chain calls in a certain extent, simplifies the process we implement some tedious to write, and on its way around its object more concentrated, using dot syntax pull close the distance we operation object, to a certain extent, at the time of maintenance is also easier to find the key information in a piece of code

Because of Swift’s natural syntax advantage, using chain programming for closures is much more comfortable and easy to use than using OC code, so if you know Swift syntax, learning chain programming is a good place to start!

Put this to use

1. Customize the pop-up view

Import UIKit enum OtherMsgItemMode {case left case Right} class OtherMsgView: UIView, PopupProtocol, XIBProtocol { @IBOutlet weak var msgLab: UILabel! @IBOutlet weak var leftBtn: UIButton! @IBOutlet weak var rightBtn: UIButton! typealias ItemHandlerType = ((OtherMsgItemMode) -> Void) private var leftTitle: String? // private var rightTitle: String? // private var description: String? // private var action: ItemHandlerType? // override func layoutSubviews() { super.layoutSubviews() self.layer.cornerRadius = 12 self.backgroundColor = .white leftBtn.setTitle(leftTitle, for: .normal) rightBtn.setTitle(rightTitle, for: .normal) msgLab.text = description leftBtn.addTarget(self, action: #selector(leftTarget)) rightBtn.addTarget(self, action: #selector(rightTarget)) } @IBAction func click(_ sender: UIButton) { PopupController.dismiss(self) } @objc func leftTarget() { PopupController.dismiss(self) action? (.left) } @objc func rightTarget() { PopupController.dismiss(self) action? (.right) } } extension Aiolia_Soul_OtherMsgView { func open(_ viewController: UIViewController?) -> Void { PopupController.show(self, presentingViewController: viewController) return } func action(_ handler: @escaping ItemHandlerType) -> Self { self.action = handler return self } func itemTitle(left: String, right: String) -> Self { self.leftTitle = left self.rightTitle = right return self } func description(_ text: String) -> Self { self.description = text return self } }Copy the code

implementation

OtherMsgView.loadFromNib()? .itemTitle(left: "Cancel ", right:" confirm ").content(" Confirm to delete account? ) .action({ (item) in }) .open(vc)Copy the code

2. Network layer encapsulation

Import Foundation import Alamofire enum HttpRequestType {case get case post} extension HttpRequestType: CustomStringConvertible { var description: String { switch self { case .get: return "GET" case .post: Class Networkkit {TypeAlias SuccessHandlerType = ((Data) -> Void) TypeAlias FailureHandlerType = ((Int, String) ->Void) typealias FinishHandlerType = ((Any?) -> Void) typealias TimeOutHandlerType = ((String) -> Void) private var requestType: HttpRequestType =. Post // Request type Private var URL: String? //URL private var headers: [String: String] = ["Accept":"application/json", "Content-Type":"application/json"]//header private var params: [String: Any]? Private var timeoutInterval: TimeInterval = 15 private var success: SuccessHandlerType? Private var failure: FailureHandlerType? Private var Finish: FinishHandlerType? Private var timeOut: TimeOutHandlerType? Private var httpRequest: Request? } // set NetworkKit (); // set NetworkKit (); Func requestType(_ type:HttpRequestType) -> Self {Self. Self. RequestType = type return self} func headers(_ headers: [String: Func params(_ params: [String: Any]?) -> Self {self.headers = headers return Self} -> Self {self.params = params return Self} func timeoutInterval(_ timeoutInterval: TimeoutInterval) -> Self {self.timeoutInterval = timeoutInterval return Self} @escaping SuccessHandlerType) -> Self {Self. Success = handler return Self} @escaping FailureHandlerType) -> Self {Self. Failure = handler return Self} @escaping FinishHandlerType) -> Self {self.finish = handler return Self} @escaping TimeOutHandlerType) -> Self {self.timeOut = handler return Self}} HttpRequest () -> Void {var dataRequest: dataRequest? If let URLString = url {progresshud.show () let method = requestType ==.get? HTTPMethod.get : HTTPMethod.post let encoding: ParameterEncoding = requestType == .get ? URLEncoding.default : JSONEncoding. Default guard let params = params else {return} // Alamofire original method, //dataRequest = Alamofire. Request (URLString, method: method, parameters: params as Parameters, encoding: encoding, headers: headers) var myRequest = URLRequest(url: URL(string: URLString)! as URL) myRequest.httpMethod = method.rawValue myRequest.httpBody = params.toJSONString()? .data(using: .utf8) myRequest.timeoutInterval = timeoutInterval myRequest.allHTTPHeaderFields = headers dataRequest = Alamofire.request(myRequest) httpRequest = dataRequest } dataRequest? .responseJSON(options: [.mutableLeaves, .allowFragments, .mutableContainers], completionHandler: { (response) in ProgressHUD.hide() guard response.error == nil else { if response.error! ._code == NSURLErrorTimedOut { //handle timeout here print("Code=-1001 The request timed out.") self.timeOut? (response.error! .localizedDescription) }else { self.failure? (response.error! ._code, response.error! .localizedDescription) } return } let data = response.data.map { String(decoding: $0, as: UTF8.self) } guard let jsonData = data else { return } self.finish? (jsondata.todictionary ())})} /// cancel the request func httpCancel() {httpRequest? .cancel() } }Copy the code

implementation

NetworkKit() .timeoutInterval(timeoutInterval) .url("\(baseURL)xx") .params(params) .requestType(.post) .timeOut { (msg)  in } .failure(handler: { (errorCode, errorMsg) in }) .finish { (result) in }.httpRequest()Copy the code

That’s all there is to chain calls. There are no complicated instructions, but there are only three conditions we need to pay attention to as we write: chain objects, chain method calls, and passing values and subsequent processing of results. If you really don’t understand it, remember that chain calls always return self.