domitall domitall -4 years ago 120
iOS Question

Calling objective-C typedef block from swift

I'm trying to call a method from swift.
The method is in a singleton written in objective-C

the block in the header file:

typedef void(^VPersonResultBlock)(Person *person, NSError *error);

- (void)askForMe:(VPersonResultBlock)block;


and here's the implementation of that method.

- (void)askForMe:(VPersonResultBlock)block
{
if (_me) block(_me,nil);
else {
[Person getMeWithBlock:^(PFObject *person, NSError *error) {
if (!error) {
_me = (Person *)person;
block(_me,nil);
}

else if (error) {
block(nil,error);
}
else {
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Operation was unsuccessful.", nil),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The operation failed to retrieve the user.", nil),
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Check your network connection and try again", nil)
};
NSError *error = [[NSError alloc] initWithDomain:@"VisesAsyncErrorDomain" code:-10 userInfo:userInfo];
block(nil,error);
}
}];
}
}


In Objective-C, I can call this and it autocompletes without confusion.

[[VDataStore instance] askForMe:^(Person *person, NSError *error) {
// do things with myself that aren't strange
}];


Now let's say I want to call the same method from swift. The bridging header is setup, with the header file imported, but swift's expectation is confusing.

VDataStore.askForMe(VDataStore)


This is what shows up in the autocomplete options

(VPersonResultBlock!) -> Void askForMe(self: VDataStore)


what I was hoping for, was for this to autocomplete into a closure, and although it appears to see all of the information correctly, what it's expecting isn't lining up with what objective-C seems to understand.

How do I call this properly from swift?

Answer Source

Directly translate your ObjC calling code to Swift is

VDataStore.instance().askForMe() {
    person, error in 
    // do things with myself that aren't strange
}

Your problem is that askForMe is instance method but you are accessing from class object VDataStore.askForMe. Swift will give you a function object that takes an instance as input.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download