Use NSProxy in Swift
Asked Answered
B

2

8

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()
  }
}
Boehmer answered 18/4, 2018 at 15:20 Comment(6)
#36479179Krispin
@MartinR it looks like an old question, I wonder, has anything changed.Boehmer
Apparently not ..,Krispin
It is a known bug: bugs.swift.org/browse/SR-1715.Krispin
@MartinR thanks for the mention. I found a couple of workarounds and might post them here soon.Boehmer
I guess most developer don't understand NSProxy or aren't even aware of it's existence. Still I think this should be fixed.Mawkish
C
1

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.

Cinch answered 30/11, 2023 at 11:42 Comment(1)
I think, this is what I've done back then.Boehmer
X
-1

NSProxy is a abstract class. Apple docs about NSProxy says "An abstract superclass defining an API for objects that act as stand-ins for other objects or for objects that don’t exist yet".

The docs about abstract class of wikipedia says:

In a language that supports inheritance, an abstract class, or abstract base class (ABC), is a class that cannot be instantiated because it is either labeled as abstract or it simply specifies abstract methods (or virtual methods).

Calling super.init() for abstract class is wrong. In second class you are not calling super.init() for abstract class but of WorkingProxyBaseClass which is a concrete class. In Objective c you have not called [super init] hence code is working.

Xavier answered 16/7, 2019 at 6:6 Comment(1)
The question is still open. How to instantiate an NSProxy subclass in Swift?Boehmer

© 2022 - 2024 — McMap. All rights reserved.