Aufruf Swift Closure Inside Closure - ios, swift

Ich habe den folgenden Code:

  twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in


twitterAPI?.getUserTimelineWithScreenName(userName, count: 100, successBlock: { ([AnyObject]!) -> Void in



}, errorBlock: { (error :NSError!) -> Void in

})



}, errorBlock: { (error :NSError!) -> Void in

println("error block")
})

Ich erhalte folgende Fehler:

Bildbeschreibung hier eingeben

Ich habe versucht, mich selbst innerhalb des äußeren Verschlusses zu sagen, aber es hat nicht funktioniert. Was vermisse ich?

AKTUALISIERT: Immer noch Buildfehler:

Bildbeschreibung hier eingeben

UPDATE: Wenn ich die getUserTimeline-Methode außerhalb der Closure positioniere, funktioniert sie. DIESE FUNKTIONIERT.

//        twitterAPI?.getUserTimelineWithScreenName("", successBlock: { (objects :[AnyObject]!) -> Void in
//
//            }, errorBlock: { (error: NSError!) -> Void in
//
//        })

Aber das tut nicht:

twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in


self.twitterAPI?.getUserTimelineWithScreenName("", successBlock: { (objects :[AnyObject]!) -> Void in

}, errorBlock: { (error: NSError!) -> Void in

})



}, errorBlock: { (error :NSError!) -> Void in


})

UPDATE: Definition der Methode getUserTimeLine

self.twitterAPI?.getUserTimelineWithScreenName(<#screenName: String!#>, successBlock: <#(([AnyObject]!) -> Void)!##([AnyObject]!) -> Void#>, errorBlock: <#((NSError!) -> Void)!##(NSError!) -> Void#>)

Bildbeschreibung hier eingeben

UPDATE: Jetzt erhalte ich einen Build-Fehler, der das fehlende Argument sideID sagt. Ich benutze diesen Konstruktor nicht einmal.

 if let twitterAPI = self.twitterAPI {

twitterAPI.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in

twitterAPI.getUserTimelineWithScreenName(userName, successBlock: { (objects :[AnyObject]!) -> Void in

}, errorBlock: { (error :NSError!) -> Void in

})


}, errorBlock: { (error :NSError!) -> Void in

})

}

Antworten:

4 für die Antwort № 1

Versuchen:

        twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in
self.twitterAPI?.getUserTimelineWithScreenName(userName, successBlock: { (objects :[AnyObject]!) -> Void in

}, errorBlock: { (error :NSError!) -> Void in
})

return  // <-- ADDED

}, errorBlock: { (error :NSError!) -> Void in
})

In diesem Fall

{ (userName, password) -> Void in
self.twitterAPI?.getUserTimelineWithScreenName("", successBlock: { (objects :[AnyObject]!) -> Void in
}, errorBlock: { (error: NSError!) -> Void in
})
}

ist eine "einzelne Ausdrucksschließung", die nicht implizit ist Void Rückkehr.

Ab Xcode 6.2 / Swift 1.1 benötigen Sie explizit return Hier.

Oder verwenden Sie Xcode 6.3 / Swift 1.2, das dieses Problem behoben hat.

Siehe diese Frage: One-Line-Schließung ohne Rückgabetyp oder Swift - 'Bool' ist kein Subtyp von 'Void'?


1 für die Antwort № 2

Ok, bei den Methodennamen, die du verwendest, rate ich, dass du die STTwitter Bibliothek. Wenn das der Fall ist, willst du so etwas:

    if let twitterAPI = self.twitterAPI {
twitterAPI.verifyCredentialsWithSuccessBlock({ (String) -> Void in
twitterAPI.getUserTimelineWithScreenName("test", successBlock: { (objects: [AnyObject]!) -> Void in
println("success")
}, errorBlock: { (error: NSError!) -> Void in
println("failure")
})
}, errorBlock: { (error: NSError!) -> Void in

})
}

Notieren Sie sich den Anruf, bevor Sie das Optionale verwenden self.twitterAPI Variable.


1 für die Antwort № 3

einfache Version, zum Beispiel. Aber mach lieber Monade

twitterAPI?.verifyCredentialsWithUserSuccessBlock({[weak self] (userName, password) in
self?.twitterAPI?.getUserTimelineWithScreenName(userName, count: 100, successBlock: {[weak self] (value: [AnyObject]!) in
// success
}) { (error: NSError!) in
// error
}
}) { (error: NSError!) in
// error
}

0 für die Antwort № 4

Dies ist eine irreführende Fehlermeldung. Das Problem ist, dass die innere Variable nicht optional sein kann if/let es.

Sieh dir das auf einem Spielplatz an ...

class Foo:NSObject {
func doThing(bug:Int,completion:((Void)->(Void))) {

}
}

let woot = Foo()
var bar:Foo? = Foo()

bar?.doThing(7, completion: {});

woot.doThing(3, completion: {

bar?.doThing(4, completion:{});

});

Es kompiliert nicht und die Nachricht

Der Ausdruckstyp "(IntegerLiteralConvertible, Vervollständigung: () -> () - $ T3) "to type" () "

Es ist nicht genau auf das Problem aufmerksam.

Also entpacke das optional

woot.doThing(3, completion: {

if let bar = bar {
bar.doThing(4, completion:{});
}

});

Und es kompiliert jetzt.

Und zu dem anderen Thema

Wenn Sie das überprüfen STTwitterAPI.h Header

- (NSObject<STTwitterRequestProtocol> *)getUserTimelineWithScreenName:(NSString *)screenName
successBlock:(void(^)(NSArray *statuses))successBlock
errorBlock:(void(^)(NSError *error))errorBlock;

ist nur eine Annehmlichkeit für die vollständige Signatur von diesem.

- (NSObject<STTwitterRequestProtocol> *)getUserTimelineWithScreenName:(NSString *)screenName
sinceID:(NSString *)sinceID
maxID:(NSString *)maxID
count:(NSUInteger)count
successBlock:(void(^)(NSArray *statuses))successBlock
errorBlock:(void(^)(NSError *error))errorBlock;

Obj-C to Swift Bridging platziert alles nach dem ersten Selektor-Chunk innerhalb der Klammern, so dass Convenience-Methoden dazu neigen, die Dinge durch Code-Vervollständigung zu verwirren, aber nicht den kanonischen Fall.

Also in deinem Fall (ohne mich zu haben) STTwitter) das ist, was du willst.

twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in

if let twitterAPI = self.twitterAPI {
twitterAPI.getUserTimelineWithScreenName("JohnSmith",sinceID:someID,maxID:anotherID,count:1000, successBlock: { (objects)[AnyObject]!) -> Void in

}, errorBlock: { (error: NSError!) -> Void in

})
}


}, errorBlock: { (error :NSError!) -> Void in


})

wie du dich entscheidest zu bevölkern sinceID , maxID und count liegt an Ihnen . Ich habe die API nie benutzt, also nicht raten. Sie könnten nicht in der Lage sein


Speisekarte