1. 程式人生 > >SWIFT閉包,介紹,使用(ALAMOFIRE封裝 非同步請求)

SWIFT閉包,介紹,使用(ALAMOFIRE封裝 非同步請求)

閉包說明:
首先說明簡明扼要的說明一下:閉包,可以看做 JAVA中匿名函式。
我們來看APPLE文件:
一個函式,可以看做一個特殊的閉包
巢狀函式,是一個捕獲其所在函式中上下文的閉包
閉包表示式,是一個寫法奇特,可以捕獲上下文變數的【匿名閉包】


那麼讓我們開始:
       我們有這樣子的一個需求:寫一個API,他需要兩個引數,第一個引數是一個 字串陣列,第二個引數是一個函式,
 這個函式的作用是向陣列中的每一個人打招呼,你可以對她說HELLO,BOY,你也可以對她說:OH,MY GOD.同時返回一個新的陣列,這個陣列中包含了對每個人說的話
那麼我們需要怎麼做呢?如果是不知道有【閉包】的情況下


==========這裡的預備知識是:高階函式,將函式作為其他函式的引數or返回值=============
那麼現在我們用高階函式來寫:
首先將上面的函式合併為一個:用高階函式來做
func sayHellotoeverybody(person:[String],fu:(eachPerson:String)->String)->[String]{
var newArray = [String]()
for eachPerson in person {
newArray.append(fu(eachPerson))
}
return newArray
}
func sayhelloFunc(eachPerson:String)->String{
print(“hello, u are so nice\(eachPerson)”)
return “hello, u are so nice\(eachPerson)”
}
呼叫的時候直接用:
let newArray = sayHellotoeverybody([“shan”,”wenzheng”,”xiaolin”],fu:sayhelloFunc)


================================================接下來我們用閉包來做===========


func sayHellotoeverybody(person:[String],fu:(eachPerson:String)->String)->[String]{
var newArray = [String]()
for eachPerson in person {
newArray.append(fu(eachPerson))
}
return newArray
}


let newArray  = sayHellotoeverybody([“dsfa”,”dsfa”,”dsaf”],fu:{(name)->String in
//這裡做你想要的操作,比如對他說你很漂亮或者很醜
//或者其他的業務操作
print(“u are so ugly\(name)”)
return “ u are so ugly \(name)"
 })


總結:從上面的函式來看,閉包最後的效果就是:隱藏了對每個人說話的函式,逼格更高,嘻嘻,

 感覺是不是 JAVA的匿名函式呢?

//對閉包的一些補充
//閉包可以儲存到變數中
let plus = {(a:Int,b:Int)->Int in
return a + b
}


//使用
let number = plus(3,5)


==================================
//閉包的型別推斷
let plus:Int = {a,b in 
return a + b
}
//括號都TM的省略了


//省略return 關鍵字
//如果閉包內只有一句話,並且這句話 return someThing
//那麼可以省略return
let plus = {a,b in a + b}
//變態的省略形參名 和 in
let plus:Int = {return $0 * $0}
=> let plus:Int = {$0 * $1)}
//幾乎沒法閱讀了
===================================
當引數列表最後一個是 函式,那麼可以使用尾隨閉包,簡化寫法
myFunc(a:Int,b:Int,c:{閉包體})
可以修改為:
myFucn(a:Int,b:Int){
$0 * $1
}
===================================
===================================
閉包的應用(對非同步操作有很好的封裝)
在一個方法中,如果其中有非同步方法,比如說網路請求。
那麼宣告一個閉包,作為這個方法的最後一個引數。
當獲取到網路請求的數值之後,執行這個引數方法。
使這個引數方法中的引數 賦值 為 網路請求下來的資料
-------
那麼在呼叫網路請求方法的時候,當閉包中有內容就說明請求成功,
可以使用了。

================

接下來是對Alamofire的非同步封裝

================

/**

方法體內部是回撥方法,此方法無需設定代理

    - parameter url:請求APIURL

    - parameter params:引數列表:雜湊

    - parameter getResultfunc:結果集

    */

classfunc getAPIresult(url:String,params:Dictionary<String,AnyObject>,getResultfunc:(ifComplieted:Bool,resultString:

String,resultNSDic:NSDictionary,resultNSArray:NSArray)->Void){

        Alamofire.request(Method.POST, url, parameters: params, encoding: ParameterEncoding.URL, headers: nil).responseString(encoding: NSUTF8StringEncoding, completionHandler: { (Response) -> Voidin

if((Response.resultasResult).isSuccess && Response.result.value != nil){

let stringValue = Response.result.value!

if(stringValue != MessageCloud.arrayNoItem && stringValue != MessageCloud.nullItemOtherLanguage && stringValue != MessageCloud.nullItemOtherLanguage){

let nsdata = stringValue.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)

do{

let nowdicData = tryNSJSONSerialization.JSONObjectWithData(nsdata!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary

if(nowdicData != nil){

//這裡處理之,所有返回資料型別第一層都是字典

if(nowdicData!["state"] as! String == "1"){

if(nowdicData!["data"] as? NSArray != nil) {

//陣列型別的資料

                                    getResultfunc(ifComplieted: true,resultString: stringValue,resultNSDic: NSDictionary(),resultNSArray: nowdicData!["data"] as! NSArray)

                                }elseif(nowdicData!["data"] as? NSDictionary != nil){

                                    getResultfunc(ifComplieted: true,resultString: stringValue,resultNSDic: nowdicData!["data"] as! NSDictionary,resultNSArray: NSArray())

                                }else{

//字串型別的資料

let returnStr = nowdicData!["data"] as? String

                                    getResultfunc(ifComplieted: true,resultString: returnStr!,resultNSDic: NSDictionary(),resultNSArray: NSArray())

                                }

                            }else{

//返回錯誤資料 ERRMSG 字典中的KEY

                                getResultfunc(ifComplieted: true,resultString: nowdicData!["errmsg"] as! String,resultNSDic: NSDictionary(),resultNSArray: NSArray())

                            }

                        }

                    }catchlet error asNSError{

//這裡處理系統錯誤,非編碼錯誤,例如:找不到伺服器,404錯誤等

//這裡應該返回CATCH

                        getResultfunc(ifComplieted: true,resultString: "\(error)",resultNSDic: NSDictionary(),resultNSArray: NSArray())

                    }

                }else{

//在汽車專案中不可能存在這種情況

                    getResultfunc(ifComplieted: true,resultString: MessageCloud.noItem,resultNSDic: NSDictionary(),resultNSArray: NSArray())

                }

            }else{

//200CODE 返回值都在這裡處理,比如說 404

                getResultfunc(ifComplieted: true,resultString: "20x 返回值,應當檢視Response的確切說明!",resultNSDic: NSDictionary(),resultNSArray: NSArray())

            }

        })

    }

==============

呼叫:

AlamofiredelegateEntity.getAPIresult("\(GLOBAL_IPADDRESS_API)RentalLocation/GetChargingStation", params: ["UserID":"\(34)","UserLa":"\(45)","UserLo":"\(98)","MapLevel":"\(2)"]) { (ifComplieted, resultString, resultNSDic, resultNSArray) -> Voidin

if(ifComplieted){

print(resultString)

            }

        }