Reputation: 655
So I'm converting this line of code
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(TidyFeed * _Nonnull item, NSDictionary<NSString *,id> * _Nullable bindings) {
return ![item.feedEntryId isEqualToString:feedEntryId];
}];
to swift code
var predicate = NSPredicate { (item: TidyFeed, bindings: NSDictionary) in
return !(item.feedEntryId == feedEntryId)
}
but I get this error
Cannot convert value of type '(TidyFeed, NSDictionary) -> Bool' to expected argument type '(AnyObject, [String : AnyObject]?) -> Bool'
has anyone encounter this error when using blocks?
Additional Info
Swift code
apiClient.dismissFeed(feedEntryId, completion: {(responseObject: AnyObject, error: NSError) -> Void in
})
Error
Cannot convert value of type '(AnyObject, NSError) -> Void' to expected argument type 'AFAPIOperationCompletionBlock!'
and here's the completion block code of AFAPIOperationCompletionBlock
- (void) completion:(id)responseObject error:(NSError *)error
Upvotes: 1
Views: 4258
Reputation: 540075
In Objective-C, the first parameter id evaluatedBlock
of the closure
can be substituted by any object pointer, like TidyFeed *
, and that
is a known method to avoid additional pointer conversion if you know for sure that the evaluated objects are in fact of that type.
Swift however does not allow this, and you have to cast the pointer inside the block:
let predicate = NSPredicate { (item: AnyObject, _) -> Bool in
return (item as! TidyFeed).feedEntryId != feedEntryId
}
This will crash if the block is called with an object which is not
of the type TidyFeed
. A safe version is
let predicate = NSPredicate { (item: AnyObject, _) -> Bool in
if let feed = item as? TidyFeed {
return feed.feedEntryId != feedEntryId
} else {
return false
}
}
with an optional cast. This can be written more compactly as:
let predicate = NSPredicate { (item: AnyObject, _) -> Bool in
return (item as? TidyFeed)?.feedEntryId != feedEntryId
}
Note also how you can use the wildcard pattern _
for the unused
bindings
parameter.
Upvotes: 0