Search code examples
swiftblock

How to pass a completion block to another class in Swift


In Objective-C, I used this handling of a completion-block that now must be transformed to Swift:

in DetailDisplayController.h

typedef void (^AddedCompletitionBlock)(BOOL saved, NSString *primarykey, NSUInteger recordCount);

@interface DetailDisplayController : UITableViewController

@property (nonatomic, copy) AddedCompletitionBlock completionBlock;
@property (strong, nonatomic) Details *detail;

in DetailDisplayController.m

- (void) saveClicked:(id)sender
{  
   // retrieve PK
   NSString *objectId = [[[_detail objectID] URIRepresentation] absoluteString];

   if (self.completionBlock != nil)
   {
       self.completionBlock(_rowChanged, objectId, [_fetchedResultsController.fetchedObjects count]);
   }

_rowChanged and _fetchedResultsController are instance-variables

and in DetailViewController.m a the calling class, the passed block is used

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   if ([segue.identifier isEqualToString:@"DetailDisplay"])
   {
       DetailDisplayController *detailDisplayController = segue.destinationViewController; 
       ...
       detailDisplayController.completionBlock = ^(BOOL saved, NSString *sorter, NSUInteger recordCount)
       {
        if (saved)
           ...

How can I do this in Swift?


Solution

  • Here's the equivalent pieces that you need in Swift:

    typealias AddedCompletionBlock = (saved: Bool, primaryKey: String, recordCount: Int) -> Void
    
    var completionBlock: AddedCompletionBlock? = nil
    
    completionBlock = {saved, primaryKey, recordCount in
        print("\(saved), \(primaryKey), \(recordCount)")
    }
    
    completionBlock?(saved: true, primaryKey: "key", recordCount: 1)
    

    You probably want to have a good read of the "Function Types" and "Closures" sections of the Apple Swift docs.