swiftproxy-patternnsproxy

Use NSProxy in Swift


How to create an NSProxy subclass in Swift?

Trying to add any of the init methods fails with error: "Super init can't be called outside of the initializer", or "Super init isn't called on all paths before returning from initializer"

error1 error2

Using Objective-C subclass as a Base class works, but feels more like a hack:

// Create a base class to use instead of `NSProxy`
@interface WorkingProxyBaseClass : NSProxy
- (instancetype)init;
@end

@implementation WorkingProxyBaseClass
- (instancetype)init
{
  if (self) {

  }
  return self;
}
@end



// Use the newly created Base class to inherit from in Swift
import Foundation

class TestProxy: WorkingProxyBaseClass {
  override init() {
    super.init()
  }
}

Solution

  • Simple solution: make Objective-C class that inherits from NSProxy and then inherit Swift class from it.

    Example at my GitHub: https://gist.github.com/SoundBlaster/0e53bae4ab814537c5868564d95eb553

    // Objective-C Header BaseProxyForSwift.h
    
    NS_ASSUME_NONNULL_BEGIN
    
    NS_SWIFT_NAME(BaseProxyForSwift)
    @interface BaseProxyForSwift : NSProxy
    
    + (id)with:(id)object;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    // Objective-C Implementation BaseProxyForSwift.m
    
    #import "BaseProxyForSwift.h"
    
    @interface BaseProxyForSwift ()
    @property (nonatomic, strong) id object;
    @end
    
    @implementation BaseProxyForSwift
    
    + (id)with:(id)object {
        BaseProxyForSwift *res = [self alloc];
        res.object = object;
        return res;
    }
    
    @end
    
    // Swift Implementation BaseSwiftProxy.swift
    
    import Foundation
    
    public class BaseSwiftProxy: BaseProxyForSwift {}
    
    // Usage in Swift
    
    let a = NSObject()
    let p = BaseSwiftProxy.with(a)
    

    Don't forget about Objective-C Bridging Headers if you will mix languages in one project: https://developer.apple.com/documentation/swift/importing-objective-c-into-swift.