美文网首页Weex开发技巧weex社区
weex在iOS中的扩展模块源码分析(以Storage扩展为例)

weex在iOS中的扩展模块源码分析(以Storage扩展为例)

作者: KChuck | 来源:发表于2017-12-06 16:55 被阅读66次

    Weex在 iOS 下选择了 JavaScriptCore 内核,解析Javascript代码,最后在iOS native端进行界面渲染、数据存储或网络通信等。即,最后在iOS 客户端执行的还是原生的OC或Swift代码。

    以Storage扩展为例,在Xcode工程中的实现是WXStorageModule类。在.h文件中有以下方法。

    #import "WXModuleProtocol.h"
    
    @interface WXStorageModule : NSObject <WXModuleProtocol>
    
    - (void)length:(WXModuleCallback)callback;
    
    - (void)getAllKeys:(WXModuleCallback)callback;
    
    - (void)setItem:(NSString *)key value:(NSString *)value callback:(WXModuleCallback)callback;
    
    - (void)setItemPersistent:(NSString *)key value:(NSString *)value callback:(WXModuleCallback)callback;
    
    - (void)getItem:(NSString *)key callback:(WXModuleCallback)callback;
    
    - (void)removeItem:(NSString *)key callback:(WXModuleCallback)callback;
    
    @end
    
    1. length:方法,获取已经存储数据的条数,
    - (void)length:(WXModuleCallback)callback
    {
        if (callback) {
            callback(@{@"result":@"success",@"data":@([[WXStorageModule memory] count])});
        }
    }
    

    2.getAllKeys:获取存储数据的全部key值,每个key对应一条数据。

    - (void)getAllKeys:(WXModuleCallback)callback
    {
        if (callback) {
            callback(@{@"result":@"success",@"data":[WXStorageModule memory].allKeys});
        }
    }
    

    3.以setItem: value: callback:方法(存储数据),实现的关键是

    [self setObject:value forKey:key persistent:NO callback:callback];
    
    - (void)setObject:(NSString *)obj forKey:(NSString *)key persistent:(BOOL)persistent callback:(WXModuleCallback)callback {
        NSString *filePath = [WXStorageModule filePathForKey:key];
        if (obj.length <= WXStorageLineLimit) {
            if ([WXStorageNullValue isEqualToString:self.memory[key]]) {
                [[WXUtility globalCache] removeObjectForKey:key];
                [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
            }
            self.memory[key] = obj;
            NSDictionary *dict = [self.memory copy];
            [self write:dict toFilePath:[WXStorageModule filePath]];
            [self setInfo:@{@"persistent":@(persistent),@"size":@(obj.length)} ForKey:key];
            [self updateIndexForKey:key];
            [self checkStorageLimit];
            if (callback) {
                callback(@{@"result":@"success"});
            }
            return;
        }
        //...
    }
    
    [self write:dict toFilePath:[WXStorageModule filePath]];
    

    数据最后以数据字典的形式存储在本地文件中,且persistent参数指定了是否持久存储。非持久的数据可能在存储超过5M后被删除。

    1. 获取数据方法- (void)getItem:(NSString *)key callback:(WXModuleCallback)callback ,根据key值去读取本地存储
    NSString *value = [self.memory objectForKey:key];
      if ([WXStorageNullValue isEqualToString:value]) {
          value = [[WXUtility globalCache] objectForKey:key];
          if (!value) {
              NSString *filePath = [WXStorageModule filePathForKey:key];
              NSString *contents = [WXUtility stringWithContentsOfFile:filePath];
              if (contents) {
                  [[WXUtility globalCache] setObject:contents forKey:key cost:contents.length];
                  value = contents;
              }
          }
      }
    

    5.removeItem: 方法则根据key去删除本地对应的存储。

    if ([WXStorageNullValue isEqualToString:self.memory[key]]) {
            [self.memory removeObjectForKey:key];
            NSDictionary *dict = [self.memory copy];
            [self write:dict toFilePath:[WXStorageModule filePath]];
            dispatch_async([WXStorageModule storageQueue], ^{
                NSString *filePath = [WXStorageModule filePathForKey:key];
                [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
                [[WXUtility globalCache] removeObjectForKey:key];
            });
    }
    

    6.存储的数据总大小不能超过5M

    static NSUInteger const WXStorageLineLimit            = 1024;
    static NSUInteger const WXStorageTotalLimit           = 5 * 1024 * 1024;
    

    检查已存储的数据大小

    - (void)checkStorageLimit {
        NSInteger size = [self totalSize] - WXStorageTotalLimit;
        if (size > 0) {
            [self removeItemsBySize:size];
        }
    }
    

    如果超过5M,则删去部分非持久(根据存储的persistent字段)存储的数据

    - (void)removeItemsBySize:(NSInteger)size {
        NSArray *indexs = [[self indexs] copy];
        if (size < 0 || indexs.count == 0) {
            return;
        }
        
        NSMutableArray *removedKeys = [NSMutableArray array];
        for (NSInteger i = 0; i < indexs.count; i++) {
            NSString *key = indexs[i];
            NSDictionary *info = [self getInfoForKey:key];
            
            // persistent data, can't be removed
            if ([info[@"persistent"] boolValue]) {
                continue;
            }
            
            [removedKeys addObject:key];
            size -= [info[@"size"] integerValue];
            
            if (size < 0) {
                break;
            }
        }
        
        // actually remove data
        for (NSString *key in removedKeys) {
            [self executeRemoveItem:key];
        }
    }
    

    相关文章

      网友评论

        本文标题:weex在iOS中的扩展模块源码分析(以Storage扩展为例)

        本文链接:https://www.haomeiwen.com/subject/jxdlixtx.html