h.and.h
h.and.h

Reputation: 776

Generic class for subclassed UIViewControllers?

I have an unwinding segue in some legacy code that has too much duplication. I'm trying to cut it down.

- (IBAction)unwindWithNewData:(UIStoryboardSegue *)segue {
    if ([segue.sourceViewController isKindOfClass:DistantVC1.class]) {
        DistantVC1 *sourceVC = (DistantVC1 *)segue.sourceViewController;
        self.activeUUID = sourceVC.data.uuid;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC2.class]) {
        DistantVC2 *sourceVC = (DistantVC2 *)segue.sourceViewController;
        self.activeUUID = sourceVC.data.uuid;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC3.class]) {
       DistantVC3 *sourceVC = (DistantVC3 *)segue.sourceViewController;
       self.activeUUID = sourceVC.data.uuid;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC4.class]) {
        DistantVC4 *sourceVC = (DistantVC4 *)segue.sourceViewController;
        self.activeUUID = sourceVC.data.uuid;
    }
}

I'd love to store a generic version of whatever viewcontroller at the top of the function and just populate it with the appropriate one, then call the self.activeUUID setter once. Something like:

- (IBAction)unwindWithNewData:(UIStoryboardSegue *)segue {
    id sourceVC;
    if ([segue.sourceViewController isKindOfClass:DistantVC1.class]) {
        sourceVC = (DistantVC1 *)segue.sourceViewController;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC2.class]) {
        sourceVC = (DistantVC2 *)segue.sourceViewController;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC3.class]) {
       sourceVC = (DistantVC3 *)segue.sourceViewController;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC4.class]) {
       sourceVC = (DistantVC4 *)segue.sourceViewController;
    }
    self.activeUUID = sourceVC.data.uuid;
}

Any ideas? Thanks!

Upvotes: 1

Views: 57

Answers (2)

h.and.h
h.and.h

Reputation: 776

And here's a Swift 4.2 version:

protocol ActiveIDProvider {
    var activeUUID: String { get }
}

class myVC1: UIViewController { }

extension myVC1: ActiveIDProvider {
    var activeUUID: String {
        get {
            return "1"
        }
    }
}
    @IBAction func unwindWithNewData(_ segue: UIStoryboardSegue) {
        var sourceVC: ActiveIDProvider

        if segue.source.isKind(of: myVC1.self) {
            sourceVC = segue.source as! myVC1
        } else if segue.source.isKind(of: myVC2.self) {
            sourceVC = segue.source as! myVC2
        } else if segue.source.isKind(of: myVC3.self) {
            sourceVC = segue.source as! myVC3
        } else if segue.source.isKind(of: myVC4.self) {
            sourceVC = segue.source as! myVC4
        }

        self.activeUUID = sourceVC.activeUUID
    }

Upvotes: 0

Joshi
Joshi

Reputation: 873

Yup, as per comment use a protocol.

  @protocol ActiveIdProvider
  @property NSString *activeUUID
  @end


  @interface DistantVC1 : UIViewController <ActiveIdProvider> //repeat this block for each DistantVC class you have
  @property NSString *activeUUID
  @end
- (IBAction)unwindWithNewData:(UIStoryboardSegue *)segue {
    ActiveIdProvider *sourceVC;
    if ([segue.sourceViewController isKindOfClass:DistantVC1.class]) {
        sourceVC = (DistantVC1 *)segue.sourceViewController;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC2.class]) {
        sourceVC = (DistantVC2 *)segue.sourceViewController;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC3.class]) {
       sourceVC = (DistantVC3 *)segue.sourceViewController;

    } else if ([segue.sourceViewController isKindOfClass:DistantVC4.class]) {
       sourceVC = (DistantVC4 *)segue.sourceViewController;
    }
    self.activeUUID = sourceVC.data.uuid;
}

Upvotes: 2

Related Questions