Reputation: 169
I have a delegate class coded in Swift. I have an Objective-C class that has a delegate property of this Swift class. The Swift delegate class adopts an Objective-C protocol with a required property of type NSArray*. The Swift code builds a mutable array class var then returns that as [AnyObject].
The building of the mutable array and the assignment of that to the Swift class var works, but sometimes the function returns nil back to my Objective-C class.
When I set a breakpoint and step through line by line it works, but if I just let it run it returns nil every time.
I have also put in log statements that verify the Swift class builds the mutable array every time but the Objective-C code keeps getting nil. The only thing I have gotten to work is to change my Objective-C protocol property to NSMutableArray but that seem like I am bypassing the problem. How can I make this work using NSArray?
If I make the Swift code return NSArray! I get a compile error saying the Swift class does not implement the required delegate method.
If I change the Swift code to return
Array<AnyObject>
it compiles but still has the same problem of returning nil to my Objective-C class.
The Objective-C protocol looks like this:
@protocol MySocialDelegate <NSObject>
-(NSArray*)availableChannels;
@end
The Swift delegate class looks like this:
class MySocialDelegateSwiftClass: NSObject, MySocialDelegate {
private var socialChannels = NSMutableArray()
func availableChannels() -> [AnyObject]! {
if ( self.socialChannels.count == 0 ) {
let channel = ...getChannel()
if ( channel != nil && channel?.guid != nil ) {
self.socialChannels.addObject(channel)
}
if( someCondition ) {
let channel = ...getChannel()
if ( channel != nil && channel?.guid != nil ) {
self.socialChannels.addObject(channel!)
}
}
}
// self.socialChannels will contain 2 objects
return self.socialChannels as [AnyObject]
}
}
And the Objective-C class that calls into that Swift delegate looks something like this:
ViewController *vc = [[UIStoryboard storyboardWithName...
vc.socialDelegate = instanceOfMySocialDelegateSwiftClass;
if([vc.socialDelegate respondsToSelector:@selector(availableChannels)])
vc.availableChannels = [vc.socialDelegate availableChannels];
// vc.availableChannels will be nil
Upvotes: 1
Views: 1408
Reputation: 169
I fixed my issue. The Objective-C code was trying to assign the NSArray returned from the Swift code to a weak property. I never even noticed the weak property. I changed it to strong and it works. I thought the issue was with the cast to AnyObject.
Upvotes: 0
Reputation: 3146
Have you tried returning a NSArray in the Swift implementation of availableChannels
?
private var socialChannels = NSMutableArray()
func availableChannels() -> NSArray? {
...
return self.socialChannels // socialChannels is a NSMutableArray
}
Upvotes: 0