首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Typhoon将XML 1.x实现迁移到2.x

Typhoon将XML 1.x实现迁移到2.x
EN

Stack Overflow用户
提问于 2015-08-28 03:57:35
回答 2查看 38关注 0票数 1

我有一个带有多个XML文件的Typhoon1.x实现。我有多个应用依赖于一个公共的库。我有一个默认的xml文件,其中包含针对不同应用程序的“默认”实现的公用库。然后,每个应用程序都有自己的xml文件,该文件能够覆盖为键定义的对象类型。此覆盖是通过自定义工厂完成的。

库xml:

代码语言:javascript
复制
<!-- DEFAULT MENU -->
<component class="my_menu" key="menu_default"/>

应用1 xml:

代码语言:javascript
复制
<!-- APP 1 MENU -->
<component class="my_app1_menu" key="menu"/>

应用2 xml:

代码语言:javascript
复制
<!-- APP 2 MENU -->
<!-- None - use default -->

然后,我的自定义工厂接受一个键值,尝试访问Typhoon中的" key“。如果为'nil',则再次尝试访问:"key“+ "_default”。

我的工厂方法:

代码语言:javascript
复制
- (id) componentForKey:(NSString *)key
{
    TyphoonComponentFactory *factory = [TyphoonComponentFactory defaultFactory];
    @try {
        id obj = [factory componentForKey:key];
        if (obj) {
            return obj;
        }
    }
    @catch (NSException *exception) {
        DLog(@"Couldn't find %@", key);
        DLog(@"Nope");
    }
    // Try Default
    @try {
        key = [NSString stringWithFormat:@"%@_default", key];
        id obj = [factory componentForKey:key];
        if (obj) {
            return obj;
        }
    }
    @catch (NSException *exception) {
        DLog(@"Couldn't find %@", key);
        DLog(@"No Default");
        DLog(@"Exception: %@", exception);
    }

    return nil;
}

因为Typhoon的XML实现在2.x版本中停止了。我想超越1.x和我们当前的XML文件。然而,我很难找到一个可以工作的实现。

这一点很重要的原因是,每个应用程序本质上都是由库行为定义的基础应用程序的自定义皮肤。随着新特性的添加,该库的typhoon将填充"_default“定义。然后,当我们使用最新版本的库启动每个应用程序时,至少我们定义了一个基本实现,这样我们就不必到处跟踪'nil‘值。

EN

回答 2

Stack Overflow用户

发布于 2015-08-28 09:00:04

是的,不幸的是,从Typhoon2.x开始不支持XML。然而,您希望实现的功能得到了‘组装’风格的配置的良好支持。总而言之:

  • 定义可以模块化并组织到多个部件文件中。这些文件可能是refer to each other
  • 在启动时可以用一个程序集替换另一个程序集。这可以是程序集的子类,或者如果程序集由协议支持,则是该协议的另一个实现。(实际上,只要程序集响应相同的消息,即提供命名定义,则Typhoon并不关心)。

示例:

假设您有以下顶级程序集:

代码语言:javascript
复制
@interface MyAppAssembly : TyphoonAssembly

@property(nonatomic, strong, readonly) LibraryAssembly *library;

@end

您可以按如下方式激活它:

代码语言:javascript
复制
MyAppAssembly *assembly = [[MyAppAssembly new] 
    activateWithCollaboratingAssemblies:[CustomizedLibraryAssembly new]];

在启动时,Typhoon会说:

代码语言:javascript
复制
CustomizedLibraryAssembly will act in place of LibraryAssembly

CustomizedLibraryAssembly中,您可以覆盖任何您喜欢的定义。

感谢您成为Typhoon的早期使用者。如果您在移植到最新版本时需要帮助,请通过电子邮件发送,我们很乐意为您提供帮助。

票数 0
EN

Stack Overflow用户

发布于 2015-09-02 02:14:55

所以我想出了一个解决方案,我们几乎完全转移了,使用Typhoon 3.x。

代码语言:javascript
复制
@interface LibAssembly : TyphoonAssembly
@end

@implementation LibAssembly

- (id) menu {
    return [TyphoonDefinition withClass:[MyMenu class]];
}

@end

然后对于每个应用程序:

代码语言:javascript
复制
@interface AppAssembly : LibAssembly
@end

@implementation AppAssembly

- (id) menu {
    return [TyphoonDefinition withClass:[AppMenu class]];
}

@end

而我的工厂方法更改为:

代码语言:javascript
复制
- (id) componentForKey:(NSString *)key
{
    // Check Init
    if (!self.assembly) {
        @throw @"Assembly not initialized properly - please call 'initWithAssemblerClass:' first";
    }

    SEL selector = NSSelectorFromString(key);
    if ([self.assembly respondsToSelector:selector]) {
        return [self.assembly performSelector:selector];
    }
    return nil;
}

+ (void) initWithAssemblerClass:(Class)assemblerClass
{
    TyphoonAssembly *assembly = [assemblerClass new];
    [assembly activate];
    [MyFactory setAssembly: assembly];
}

然后,我们只需向每个应用程序的委托添加一个初始化步骤:

代码语言:javascript
复制
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // INIT TYPHOON
    [MyFactory initWithAssemblerClass:[AppAssembly class]];
...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32258370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档