Chamando fechamento rápido dentro de fechamento - ios, swift

Eu tenho o seguinte código:

  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")
})

Estou recebendo os seguintes erros:

insira a descrição da imagem aqui

Eu tentei dizer auto dentro do fechamento externo, mas não funcionou. o que estou perdendo?

ATUALIZADO: ainda com erros de construção:

insira a descrição da imagem aqui

ATUALIZAÇÃO: Se eu colocar o método getUserTimeline fora do fechamento, ele funcionará. Isso funciona.

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

Mas isso NÃO:

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: Definição do método getUserTimeLine

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

insira a descrição da imagem aqui

UPDATE: Agora, estou recebendo um erro de compilação dizendo missing argument sinceID. Eu nem estou usando esse construtor.

 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

})

}

Respostas:

4 para resposta № 1

Experimentar:

        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
})

Nesse caso

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

é um "fechamento de expressão única" que tem implícito não Void Retorna.

A partir do Xcode 6.2 / Swift 1.1, você precisa de return Aqui.

Ou, use o Xcode 6.3 / Swift 1.2 que corrigiu esse problema.

Veja esta pergunta: Fechamento de uma linha sem tipo de retorno ou Swift - 'Bool' não é um subtipo de 'Void'?


1 para resposta № 2

Ok, pelos nomes de método que você está usando, eu estou supondo que você está usando o STTwitter biblioteca. Se for esse o caso, você vai querer algo assim:

    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

})
}

Anote a chamada deixar antes de usar o opcional self.twitterAPI variável.


1 para resposta № 3

versão simples, por exemplo. Mas melhor fazer mônada

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 para a resposta № 4

Esta é uma mensagem de erro realmente enganosa. O problema é que a variável interna não pode ser do tipo opcional, então você precisa if/let isto.

Confira isso em um playground ...

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:{});

});

Não compila e a mensagem

Não é possível converter o tipo de expressão "(IntegerLiteralConvertible, conclusão: () -> () - $ T3) "para digitar" () "

Não é exatamente esclarecedor para o problema.

Então você desembrulha o opcional

woot.doThing(3, completion: {

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

});

E agora compila.

E para a outra questão

Se você verificar o STTwitterAPI.h cabeçalho

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

é apenas uma conveniência para a assinatura completa disso.

- (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 para Swift coloca tudo após o primeiro bloco do seletor dentro dos colchetes, então os métodos de conveniência tendem a confundir as coisas pelo código completando, mas não fornecendo o caso canônico.

Então, no seu caso (sem eu ter STTwitter) isso é o que você quer.

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


})

como você escolhe preencher sinceID , maxID e count Cabe a você . Eu nunca usei a API, então não vou adivinhar. Eles podem ser "incapazes"


Cardápio