Calling Swift Closure Inside Closure

前端 未结 4 1222
礼貌的吻别
礼貌的吻别 2021-01-08 00:26

I have the following code:

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


            twitterAPI?.getUserTimelin         


        
4条回答
  •  时光取名叫无心
    2021-01-08 01:02

    This is a really misleading error message. The problem is that the inner variable can't be of optional type so you need to if/let it.

    Check this out in a 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:{});
    
    });
    

    It doesnt compile and the message

    Cannot convert the expression type '(IntegerLiteralConvertible, completion:()->()-$T3)' to type '()'

    Isn't exactly illuminating to the problem.

    So you unwrap the optional

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

    And it now compiles.

    And to the other issue

    If you check the STTwitterAPI.h header

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

    is just a convenience for the full signature of this.

    - (NSObject *)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 places everything after the the first selector chunk inside the brackets so convenience methods tend to confuse things by code completing but not providing the canonical case.

    So in your case (without me having STTwitter) this is what you want.

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

    how you choose to populate sinceID , maxID and count is up to you . I've never used the API so won't guess. They might be nil'able

提交回复
热议问题