Может быть, это полезно
func getData(_ args: Any..., completion: @escaping ((Any)->Any)){
print(args)
completion(11)
}
Но тип функции не может принудительно использовать Any, вы можете использовать enum для смешивания типов безопасности.
var valid: Bool = false
func getXFromServer(arg1: String, arg2: Int, arg3: Bool, completion: ((String)->Void)? = nil){}
func getYDataFromServer(completion: @escaping (Bool)->Void){
// session.dataTask(with: URLRequest()) { data, response, error in
// handleServerResponse(){ valid
valid.toggle()
print(valid)
if valid
{
MixGetData.XYZ.run{ MixCompletion.XYZ{ firstY.run{MixCompletion.Y(completion) } }}
}
else {
completion(false)
}
// }
// }.resume()
}
func getZDataFromServer(arg1: Int, completion: @escaping (String)->Bool){}
func getXYZDataFromServer(completion: @escaping ()->Void){
completion()
}
enum MixCompletion{
case X(((String)->Void)?)
case Y((Bool)->Void)
case Z((String)->Bool)
case XYZ(()->Void)
}
enum MixGetData{
case X( String, Int, Bool )
case Y
case Z(Int)
case XYZ
func run(completion: (() -> MixCompletion)? = nil){
if (completion == nil) {
switch (self) {
case let .X(arg1, arg2, arg3) : getXFromServer(arg1: arg1, arg2: arg2, arg3: arg3, completion : nil)
case let .Z(arg1) : getZDataFromServer(arg1: arg1, completion: {_ in return false})
case .Y : getYDataFromServer(completion: {_ in})
case .XYZ : getXYZDataFromServer(completion: {})
}}
else {
switch (self, completion!()) {
case (let .X(arg1, arg2, arg3), let .X(comp)): getXFromServer(arg1: arg1, arg2: arg2, arg3: arg3, completion : comp)
case (let .Z(arg1), let .Z(comp) ) : getZDataFromServer(arg1: arg1, completion: comp)
case (.Y, let .Y(comp)) : getYDataFromServer(completion: comp)
case (.XYZ, let .XYZ(comp)) : getXYZDataFromServer(completion: comp)
default: break
}
}
}
}
let firstY = MixGetData.Y
firstY.run()
firstY.run{MixCompletion.Y{bool in print (bool)}}
Другой способ заключается виспользовать универсальную функцию.Также вы можете комбинировать оба:
func getYDataFromServer(completion: @escaping (Bool)->Void){
// session.dataTask(with: URLRequest()) { data, response, error in
// handleServerResponse(){ valid
valid.toggle()
print(valid)
if valid
{
getData(name: "XYZ", array: "") { getData(name: "Y", array: "", completion: completion)}
}
else {
completion(false)
}
// }
// }.resume()
}
func getData<T>(name: String , array: Any... , completion: T ){
switch name {
case "Y":
getYDataFromServer(completion: completion as! (Bool)-> Void)
case "X":
let arg1 = array[0] as! String; let arg2 = array[1] as! Int; let arg3 = array[2] as! Bool
getXFromServer(arg1: arg1, arg2: arg2, arg3: arg3, completion: completion as? (String)-> Void)
case "Z":
let arg1 = array[0] as! Int
getZDataFromServer(arg1: arg1, completion: completion as! (String)-> Bool)
case "XYZ":
getXYZDataFromServer(completion: completion as! ()-> Void)
default:
break;
}
}
getData(name: "Y", array : "", completion: { bool in print (123) } as (Bool)-> Void )
Я знаю, это раздражает, если есть более четырех типов для ввода.Но это единственный способ написать безопасный код.Дайте нам знать, если вам повезет.
Если вам просто нужно завершить результат, возможно, это то, что вы хотите.
func handleServerResponse<T, U>(_ alternative : (T) -> () , _ completion : @escaping (U) -> (), _ handler : U , _ terminator : () , _ resValid : Bool){
if resValid {
alternative( completion(handler) as! T )
}
else {
terminator
}
}
func getYDataFromServer(completion: @escaping (Bool)->Void){
response.toggle()
// session.dataTask(with: URLRequest()) { data, response, error in
handleServerResponse({(a) in getXYZDataFromServer {a
}}, { (a: @escaping (Bool)->Void) in getYDataFromServer(completion: a) }, completion, completion(true), response)
или
handleServerResponse( { (a) in getXYZDataFromServer{a}} , { (a: @escaping (Bool)->Void) in getZDataFromServer(arg1: 1, completion: { (s) -> Bool in
a
return false
})}, completion, completion(true), response)
У меня это хорошо работает.