Шаблон прокси в iOS - Swift
Мне нужно создать шаблон прокси в iOS, используя swift
Я пробовал это с помощью Objective C и вот код
MyProtocol.h
#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
@required
-(void)testMessage;
@end
TestBO.h
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
@interface TestBO : NSObject <MyProtocol>
@end
TestBO.m
#import "TestBO.h"
@implementation TestBO
-(void)testMessage{
NSLog(@"Test Message");
}
@end
TestProxyHandler.h
#import <Foundation/Foundation.h>
@interface TestProxyHandler : NSProxy
@property (nonatomic, strong) id object;
- (instancetype)initWithProtocol:(Protocol *)protocol andObject:(Class)clazz;
- (void)forwardInvocation:(NSInvocation *)invocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector;
@end
TestProxyHandler.m
#import "TestProxyHandler.h"
#import "TestBO.h"
@implementation TestProxyHandler
- (instancetype)initWithProtocol:(Protocol *)protocol andObject:(Class)clazz{
if ([clazz conformsToProtocol:@protocol(MyProtocol)]) {
self.object = [[clazz alloc] init];
}else{
NSLog(@"Error it does not conform to protocol");
}
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation{
NSString *selString = NSStringFromSelector(invocation.selector);
NSLog(@"Called %@",selString);
[invocation invokeWithTarget:self.object];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
return [self.object methodSignatureForSelector:selector];
}
@end
Я вызвал его, используя
id <MyProtocol> delegate = (TestBO *)[[TestProxyHandler alloc] initWithProtocol:@protocol(MyProtocol) andObject:[TestBO class]];
[delegate testMessage];
Но я не могу заставить его работать в Swift, даже initialzier показывает, что сообщение
TestHandler.swift
import Foundation
class TestHandler: NSProxy {
var object: AnyObject
convenience override init(`protocol`: Protocol, andObject clazz: AnyClass) {
if clazz.conformsToProtocol() {
self.object = clazz()
}
else {
NSLog("Error it does not conform to protocol")
}
}
}
У кого-нибудь есть подсказки, чтобы сделать это в быстрой?
РЕДАКТИРОВАТЬ:
В Java вы можете создать реализацию метода во время выполнения с помощью вызова Proxy.newProxyInstance, но можно ли это сделать в iOS? используя swift? Любая подсказка?
1 ответ
По сравнению с Objective C и Swift, Swift предлагает крайне ограниченный доступ к языку во время выполнения. Так что на основании моих исследований до сих пор это не может быть сделано:(
Я даже попытался создать подкласс класса NSProxy в swift, но просто не мог вызвать super.init, и код никогда не компилируется, но в цели C работает то же самое.
Таким образом, я в конечном итоге сделал этот подход
Я создал протокол, используя
@objc protocol SomeProt {
// Some method
}
Обратите внимание, что ключевое слово @objc перед протоколом имеет важное значение, иначе вы не сможете передать его как переменную, также добавление @objc ограничивает использование протокола целевыми функциями времени выполнения c, поэтому не ожидайте получить полные возможности протоколов в swift.
public func someMethod(`protocol` : Protocol, implementation : AnyClass) {
let isImplemented : Bool = implementation.conformsToProtocol(`protocol`)
// some code
}
Если вам нужно использовать его в каком-то словаре или местах, где он должен соответствовать классу NSCopying, используйте
NSStringFromProtocol
а также
NSProtocolFromString
методы
Теперь я написал целевой класс помощника c, чтобы сделать инициализацию
ObjcHelper.h
#import <Foundation/Foundation.h>
@interface ObjcHelper : NSObject
+(NSObject *)objectForClass:(Class)clazz;
@end
ObjcHelper.m
#import "ObjcHelper.h"
@implementation ObjcHelper
+ (NSObject *)objectForClass:(Class)clazz{
return [[clazz alloc] init];
}
@end
Теперь, чтобы использовать это
let prot : SomeProt = ObjcHelper.objectForClass(NSClassFromString("PROT_HANDLER_CLASS_NAME")) as! SomeProt
Однако в будущем, если кто-то может предложить лучший ответ, пожалуйста, не забудьте опубликовать его здесь