Шаблон прокси в 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

Однако в будущем, если кто-то может предложить лучший ответ, пожалуйста, не забудьте опубликовать его здесь

Другие вопросы по тегам