iOS 根据规则(服务器返回数据)跳转到指定的界面

97 篇文章 0 订阅

在开发过程中我们经常会遇到对接推送,推送的类型可能有很多种

1、接到推送,我们跳转到推送内容的详情页面

2、接到推送,我们跳转到一个网页

......

还有很多的情况,这个时候我们就要根据数据类型的不同进行判断,但是如果页面有很多我们就要写一大堆if else判断或switch判断。 这样做就显得很low了,而且不是非常的灵活了,而且后续如果我们增加其他页面的跳转就更不好处理了。

这个时候我们就需要Runtime来实现。

首先,我们要和后台定义后一个规则,这个规则不要去轻易变动

例如:

@{
     // 类名
     @"className" : @"DemoViewController", 
     // 数据参数
     @"propertys" : @{ @"name": @"test", 
                       @"age": @3 },
     // 调用方法名
     @"method" : @"refreshUserInformation"
 };

真时候我们就要创建很多个类似DemoViewController的类

#import <UIKit/UIKit.h>
// 由于使用的KVC赋值,如果不想把这两个属性暴露出来,把这两个属性写在.m文件也可以
@interface DemoViewController : UIViewController
@property (nonatomic,strong) NSString *name;/*!< 用户名 */
@property (nonatomic,strong) NSNumber *age;/*!< 用户年龄 */
/** 使用反射机制反射为SEL后,调用的方法 */
- (void)refreshUserInformation;
@end

这个时候如果后台来一条消息我们要如何操作呢?这个时候我们就要正式使用runtime


/**
 *  跳转界面
 */
- (void)push:(NSDictionary *)params{
    // 类名
    NSString *class =[NSString stringWithFormat:@"%@", params[@"class"]];
    const char *className = [class cStringUsingEncoding:NSASCIIStringEncoding];
    // 从一个字串返回一个类
    Class newClass = objc_getClass(className);
    if (!newClass) {
        // 创建一个类
        Class superClass = [NSObject class];
        newClass = objc_allocateClassPair(superClass, className, 0);
        // 注册你创建的这个类
        objc_registerClassPair(newClass);
    }
    // 创建对象
    id instance = [[newClass alloc] init];
    NSDictionary *propertys = params[@"propertys"];
    [propertys enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        // 检测这个对象是否存在该属性
        if ([self checkIsExistPropertyWithInstance:instance verifyPropertyName:key]) {
            // 利用kvc赋值
            [instance setValue:obj forKey:key];
        }
    }];
    // 获取导航控制器
    UITabBarController *tabVC = (UITabBarController *)self.window.rootViewController;
    UINavigationController *pushClassStance = (UINavigationController *)tabVC.viewControllers[tabVC.selectedIndex];
    // 跳转到对应的控制器
    [pushClassStance pushViewController:instance animated:YES];
    NSDictionary *methods   = params[@"method"];
    [methods enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        // 检测这个对象是否存在该属性
        if ([self checkIsExistMethodWithInstance:instance verifyPropertyName:methods[key]]) {
            // 从字典中获取方法名,并调用对应的方法
            SEL selector = NSSelectorFromString(methods[key]);
            [instance performSelector:selector];
        }
    }];
}

检测这个类有没有这个属性 


/**
 *  检测对象是否存在该属性
 */
- (BOOL)checkIsExistPropertyWithInstance:(id)instance verifyPropertyName:(NSString *)verifyPropertyName
{
    unsigned int outCount, i;
    // 获取对象里的属性列表
    objc_property_t * properties = class_copyPropertyList([instance
                                                           class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property =properties[i];
        //  属性名转成字符串
        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        // 判断该属性是否存在
        if ([propertyName isEqualToString:verifyPropertyName]) {
            free(properties);
            return YES;
        }
    }
    free(properties);
    return NO;
}

检测这个类有没有这个方法

/**
 *  检测对象是否存在该方法
 */
- (BOOL)checkIsExistMethodWithInstance:(id)instance verifyPropertyName:(NSString *)verifyMethodName
{
    unsigned int outCount, i;
    Method *methods = class_copyMethodList([instance class], &outCount);
    for ( i = 0 ; i < outCount; i++ ) {
        Method method = methods[i];
        SEL sel = method_getName(method);
        const char *name = sel_getName(sel);
        NSString *methodName = [NSString stringWithFormat:@"%s",name];
        // 判断该属性是否存在
        if ([methodName isEqualToString:verifyMethodName]) {
            free(methods);
            return YES;
        }
    }
    free(methods);
    return NO;
}

只要我们在App侧做好了对应的类,属性、方法等,我们就可以通过服务器返回规定好的数据进行跳转。我们这里也不需要写大量代码去维护还加if else、switch等判断

代码的灵活度更高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王 哪跑!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值