[ 
https://issues.apache.org/jira/browse/WEEX-213?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16656735#comment-16656735
 ] 

ASF GitHub Bot commented on WEEX-213:
-------------------------------------

Hanks10100 closed pull request #893: + [WEEX-213] [ios] expose handler for 
WXStorageModule
URL: https://github.com/apache/incubator-weex/pull/893
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m 
b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
index fbd62b93f1..05abd4ce42 100644
--- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
+++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
@@ -28,6 +28,7 @@
 #import "WXResourceRequestHandlerDefaultImpl.h"
 #import "WXNavigationDefaultImpl.h"
 #import "WXURLRewriteDefaultImpl.h"
+#import "WXStorageDefaultImpl.h"
 
 #import "WXSDKManager.h"
 #import "WXSDKError.h"
@@ -172,7 +173,7 @@ + (void)_registerDefaultHandlers
     [self registerHandler:[WXResourceRequestHandlerDefaultImpl new] 
withProtocol:@protocol(WXResourceRequestHandler)];
     [self registerHandler:[WXNavigationDefaultImpl new] 
withProtocol:@protocol(WXNavigationProtocol)];
     [self registerHandler:[WXURLRewriteDefaultImpl new] 
withProtocol:@protocol(WXURLRewriteProtocol)];
-    
+    [self registerHandler:[WXStorageDefaultImpl new] 
withProtocol:@protocol(WXStorageProtocol)];
 }
 
 + (void)registerHandler:(id)handler withProtocol:(Protocol *)protocol
diff --git a/ios/sdk/WeexSDK/Sources/Handler/WXStorageDefaultImpl.h 
b/ios/sdk/WeexSDK/Sources/Handler/WXStorageDefaultImpl.h
new file mode 100644
index 0000000000..8b4c8f2fc6
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Handler/WXStorageDefaultImpl.h
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import <Foundation/Foundation.h>
+#import "WXStorageProtocol.h"
+
+@interface WXStorageDefaultImpl : NSObject<WXStorageProtocol>
+
+@end
diff --git a/ios/sdk/WeexSDK/Sources/Handler/WXStorageDefaultImpl.m 
b/ios/sdk/WeexSDK/Sources/Handler/WXStorageDefaultImpl.m
new file mode 100644
index 0000000000..567411c40e
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Handler/WXStorageDefaultImpl.m
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "WXStorageDefaultImpl.h"
+#import "WXThreadSafeMutableDictionary.h"
+#import "WXThreadSafeMutableArray.h"
+#import "WXUtility.h"
+
+static NSString * const WXStorageDirectory            = @"wxstorage";
+static NSString * const WXStorageFileName             = @"wxstorage.plist";
+static NSString * const WXStorageInfoFileName         = 
@"wxstorage.info.plist";
+static NSString * const WXStorageIndexFileName        = 
@"wxstorage.index.plist";
+static NSUInteger const WXStorageLineLimit            = 1024;
+static NSUInteger const WXStorageTotalLimit           = 5 * 1024 * 1024;
+static NSString * const WXStorageThreadName           = 
@"com.taobao.weex.storage";
+static NSString * const WXStorageNullValue            = 
@"#{eulaVlluNegarotSXW}";
+
+@implementation WXStorageDefaultImpl
+
+- (dispatch_queue_t)targetExecuteQueue
+{
+    return [WXStorageDefaultImpl storageQueue];
+}
+
+- (NSUInteger)length
+{
+    return [[WXStorageDefaultImpl memory] count];
+}
+
+- (NSArray *)getAllKeys
+{
+    return [WXStorageDefaultImpl memory].allKeys;
+}
+
+- (void)getItem:(NSString *)key callback:(WXModuleCallback)callback
+{
+    NSString *value = [self.memory objectForKey:key];
+    if ([WXStorageNullValue isEqualToString:value]) {
+        value = [[WXUtility globalCache] objectForKey:key];
+        if (!value) {
+            NSString *filePath = [WXStorageDefaultImpl filePathForKey:key];
+            NSString *contents = [WXUtility stringWithContentsOfFile:filePath];
+            if (contents) {
+                [[WXUtility globalCache] setObject:contents forKey:key 
cost:contents.length];
+                value = contents;
+            }
+        }
+    }
+    if (!value) {
+        [self removeItem:key];
+        if (callback) {
+            callback(@{@"result":@"failed",@"data":@"undefined"});
+        }
+        return;
+    }
+    [self updateTimestampForKey:key];
+    [self updateIndexForKey:key];
+    if (callback) {
+        callback(@{@"result":@"success",@"data":value});
+    }
+}
+
+- (BOOL)removeItem:(NSString *)key {
+    if ([WXStorageNullValue isEqualToString:self.memory[key]]) {
+        [self.memory removeObjectForKey:key];
+        NSDictionary *dict = [self.memory copy];
+        [self write:dict toFilePath:[WXStorageDefaultImpl filePath]];
+        dispatch_async([WXStorageDefaultImpl storageQueue], ^{
+            NSString *filePath = [WXStorageDefaultImpl filePathForKey:key];
+            [[NSFileManager defaultManager] removeItemAtPath:filePath 
error:nil];
+            [[WXUtility globalCache] removeObjectForKey:key];
+        });
+    } else if (self.memory[key]) {
+        [self.memory removeObjectForKey:key];
+        NSDictionary *dict = [self.memory copy];
+        [self write:dict toFilePath:[WXStorageDefaultImpl filePath]];
+    } else {
+        return NO;
+    }
+    [self removeInfoForKey:key];
+    [self removeIndexForKey:key];
+    return YES;
+}
+
+#pragma mark - Utils
+- (void)setObject:(NSString *)obj forKey:(NSString *)key 
persistent:(BOOL)persistent callback:(WXModuleCallback)callback {
+    NSString *filePath = [WXStorageDefaultImpl 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:[WXStorageDefaultImpl filePath]];
+        [self setInfo:@{@"persistent":@(persistent),@"size":@(obj.length)} 
ForKey:key];
+        [self updateIndexForKey:key];
+        [self checkStorageLimit];
+        if (callback) {
+            callback(@{@"result":@"success"});
+        }
+        return;
+    }
+    
+    [[WXUtility globalCache] setObject:obj forKey:key cost:obj.length];
+    
+    if (![WXStorageNullValue isEqualToString:self.memory[key]]) {
+        self.memory[key] = WXStorageNullValue;
+        NSDictionary *dict = [self.memory copy];
+        [self write:dict toFilePath:[WXStorageDefaultImpl filePath]];
+    }
+    
+    dispatch_async([WXStorageDefaultImpl storageQueue], ^{
+        [obj writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding 
error:NULL];
+    });
+    
+    [self setInfo:@{@"persistent":@(persistent),@"size":@(obj.length)} 
ForKey:key];
+    [self updateIndexForKey:key];
+    
+    [self checkStorageLimit];
+    if (callback) {
+        callback(@{@"result":@"success"});
+    }
+}
+
+- (void)checkStorageLimit {
+    NSInteger size = [self totalSize] - WXStorageTotalLimit;
+    if (size > 0) {
+        [self removeItemsBySize:size];
+    }
+}
+
+- (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 removeItem:key];
+    }
+}
+
+- (void)write:(NSDictionary *)dict toFilePath:(NSString *)filePath{
+    [dict writeToFile:filePath atomically:YES];
+}
+
++ (NSString *)filePathForKey:(NSString *)key
+{
+    NSString *safeFileName = [WXUtility md5:key];
+    
+    return [[WXStorageDefaultImpl directory] 
stringByAppendingPathComponent:safeFileName];
+}
+
++ (void)setupDirectory{
+    BOOL isDirectory = NO;
+    BOOL fileExists = [[NSFileManager defaultManager] 
fileExistsAtPath:[WXStorageDefaultImpl directory] isDirectory:&isDirectory];
+    if (!isDirectory && !fileExists) {
+        [[NSFileManager defaultManager] 
createDirectoryAtPath:[WXStorageDefaultImpl directory]
+                                  withIntermediateDirectories:YES
+                                                   attributes:nil
+                                                        error:NULL];
+    }
+}
+
++ (NSString *)directory {
+    static NSString *storageDirectory = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        storageDirectory = 
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, 
YES).firstObject;
+        storageDirectory = [storageDirectory 
stringByAppendingPathComponent:WXStorageDirectory];
+    });
+    return storageDirectory;
+}
+
++ (NSString *)filePath {
+    static NSString *storageFilePath = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        storageFilePath = [[WXStorageDefaultImpl directory] 
stringByAppendingPathComponent:WXStorageFileName];
+    });
+    return storageFilePath;
+}
+
++ (NSString *)infoFilePath {
+    static NSString *infoFilePath = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        infoFilePath = [[WXStorageDefaultImpl directory] 
stringByAppendingPathComponent:WXStorageInfoFileName];
+    });
+    return infoFilePath;
+}
+
++ (NSString *)indexFilePath {
+    static NSString *indexFilePath = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        indexFilePath = [[WXStorageDefaultImpl directory] 
stringByAppendingPathComponent:WXStorageIndexFileName];
+    });
+    return indexFilePath;
+}
+
++ (dispatch_queue_t)storageQueue {
+    static dispatch_queue_t storageQueue;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        storageQueue = dispatch_queue_create([WXStorageThreadName 
cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_SERIAL);
+    });
+    return storageQueue;
+}
+
++ (WXThreadSafeMutableDictionary<NSString *, NSString *> *)memory {
+    static WXThreadSafeMutableDictionary<NSString *,NSString *> *memory;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        [WXStorageDefaultImpl setupDirectory];
+        
+        if ([[NSFileManager defaultManager] 
fileExistsAtPath:[WXStorageDefaultImpl filePath]]) {
+            NSDictionary *contents = [NSDictionary 
dictionaryWithContentsOfFile:[WXStorageDefaultImpl filePath]];
+            if (contents) {
+                memory = [[WXThreadSafeMutableDictionary alloc] 
initWithDictionary:contents];
+            }
+        }
+        if (!memory) {
+            memory = [WXThreadSafeMutableDictionary new];
+        }
+        //        [[NSNotificationCenter defaultCenter] 
addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil 
queue:nil usingBlock:^(__unused NSNotification *note) {
+        //            [memory removeAllObjects];
+        //        }];
+    });
+    return memory;
+}
+
++ (WXThreadSafeMutableDictionary<NSString *, NSDictionary *> *)info {
+    static WXThreadSafeMutableDictionary<NSString *,NSDictionary *> *info;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        [WXStorageDefaultImpl setupDirectory];
+        
+        if ([[NSFileManager defaultManager] 
fileExistsAtPath:[WXStorageDefaultImpl infoFilePath]]) {
+            NSDictionary *contents = [NSDictionary 
dictionaryWithContentsOfFile:[WXStorageDefaultImpl infoFilePath]];
+            if (contents) {
+                info = [[WXThreadSafeMutableDictionary alloc] 
initWithDictionary:contents];
+            }
+        }
+        if (!info) {
+            info = [WXThreadSafeMutableDictionary new];
+        }
+    });
+    return info;
+}
+
++ (WXThreadSafeMutableArray *)indexs {
+    static WXThreadSafeMutableArray *indexs;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        [WXStorageDefaultImpl setupDirectory];
+        
+        if ([[NSFileManager defaultManager] 
fileExistsAtPath:[WXStorageDefaultImpl indexFilePath]]) {
+            NSArray *contents = [NSArray 
arrayWithContentsOfFile:[WXStorageDefaultImpl indexFilePath]];
+            if (contents) {
+                indexs = [[WXThreadSafeMutableArray alloc] 
initWithArray:contents];
+            }
+        }
+        if (!indexs) {
+            indexs = [WXThreadSafeMutableArray new];
+        }
+    });
+    return indexs;
+}
+
+- (WXThreadSafeMutableDictionary<NSString *, NSString *> *)memory {
+    return [WXStorageDefaultImpl memory];
+}
+
+- (WXThreadSafeMutableDictionary<NSString *, NSDictionary *> *)info {
+    return [WXStorageDefaultImpl info];
+}
+
+- (WXThreadSafeMutableArray *)indexs {
+    return [WXStorageDefaultImpl indexs];
+}
+
+#pragma mark
+#pragma mark - Storage Info method
+- (NSDictionary *)getInfoForKey:(NSString *)key {
+    NSDictionary *info = [[self info] objectForKey:key];
+    if (!info) {
+        return nil;
+    }
+    return info;
+}
+
+- (void)setInfo:(NSDictionary *)info ForKey:(NSString *)key {
+    NSAssert(info, @"info must not be nil");
+    
+    // save info for key
+    NSMutableDictionary *newInfo = [NSMutableDictionary 
dictionaryWithDictionary:info];
+    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
+    [newInfo setObject:@(interval) forKey:@"ts"];
+    
+    [[self info] setObject:[newInfo copy] forKey:key];
+    NSDictionary *dict = [[self info] copy];
+    [self write:dict toFilePath:[WXStorageDefaultImpl infoFilePath]];
+}
+
+- (void)removeInfoForKey:(NSString *)key {
+    [[self info] removeObjectForKey:key];
+    NSDictionary *dict = [[self info] copy];
+    [self write:dict toFilePath:[WXStorageDefaultImpl infoFilePath]];
+}
+
+- (void)updateTimestampForKey:(NSString *)key {
+    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
+    NSDictionary *info = [[self info] objectForKey:key];
+    if (!info) {
+        info = @{@"persistent":@(NO),@"size":@(0),@"ts":@(interval)};
+    } else {
+        NSMutableDictionary *newInfo = [NSMutableDictionary 
dictionaryWithDictionary:info];
+        [newInfo setObject:@(interval) forKey:@"ts"];
+        info = [newInfo copy];
+    }
+    
+    [[self info] setObject:info forKey:key];
+    NSDictionary *dict = [[self info] copy];
+    [self write:dict toFilePath:[WXStorageDefaultImpl infoFilePath]];
+}
+
+- (NSInteger)totalSize {
+    NSInteger totalSize = 0;
+    for (NSDictionary *info in [self info].allValues) {
+        totalSize += (info[@"size"] ? [info[@"size"] integerValue] : 0);
+    }
+    return totalSize;
+}
+
+#pragma mark
+#pragma mark - Storage Index method
+- (void)updateIndexForKey:(NSString *)key {
+    [[self indexs] removeObject:key];
+    [[self indexs] addObject:key];
+    [self write:[[self indexs] copy] toFilePath:[WXStorageDefaultImpl 
indexFilePath]];
+}
+
+- (void)removeIndexForKey:(NSString *)key {
+    [[self indexs] removeObject:key];
+    [self write:[[self indexs] copy] toFilePath:[WXStorageDefaultImpl 
indexFilePath]];
+}
+
+@end
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m 
b/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m
index 8853dbcd3f..41a361c81c 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m
@@ -18,21 +18,10 @@
  */
 
 #import "WXStorageModule.h"
-#import "WXSDKManager.h"
-#import "WXThreadSafeMutableDictionary.h"
-#import "WXThreadSafeMutableArray.h"
-#import <CommonCrypto/CommonCrypto.h>
+#import "WXStorageProtocol.h"
+#import "WXHandlerFactory.h"
 #import "WXUtility.h"
 
-static NSString * const WXStorageDirectory            = @"wxstorage";
-static NSString * const WXStorageFileName             = @"wxstorage.plist";
-static NSString * const WXStorageInfoFileName         = 
@"wxstorage.info.plist";
-static NSString * const WXStorageIndexFileName        = 
@"wxstorage.index.plist";
-static NSUInteger const WXStorageLineLimit            = 1024;
-static NSUInteger const WXStorageTotalLimit           = 5 * 1024 * 1024;
-static NSString * const WXStorageThreadName           = 
@"com.taobao.weex.storage";
-static NSString * const WXStorageNullValue            = 
@"#{eulaVlluNegarotSXW}";
-
 @implementation WXStorageModule
 
 @synthesize weexInstance;
@@ -44,23 +33,32 @@ @implementation WXStorageModule
 WX_EXPORT_METHOD(@selector(getAllKeys:))
 WX_EXPORT_METHOD(@selector(removeItem:callback:))
 
+- (id<WXStorageProtocol>)storage
+{
+    id<WXStorageProtocol> storage = [WXHandlerFactory 
handlerForProtocol:@protocol(WXStorageProtocol)];
+    return storage;
+}
+
 #pragma mark - Export
 
 - (dispatch_queue_t)targetExecuteQueue {
-    return [WXStorageModule storageQueue];
+    id<WXStorageProtocol> storage = [self storage];
+    return [storage targetExecuteQueue];
 }
 
 - (void)length:(WXModuleCallback)callback
 {
     if (callback) {
-        callback(@{@"result":@"success",@"data":@([[WXStorageModule memory] 
count])});
+        id<WXStorageProtocol> storage = [self storage];
+        callback(@{@"result":@"success",@"data":@([storage length])});
     }
 }
 
 - (void)getAllKeys:(WXModuleCallback)callback
 {
     if (callback) {
-        callback(@{@"result":@"success",@"data":[WXStorageModule 
memory].allKeys});
+        id<WXStorageProtocol> storage = [self storage];
+        callback(@{@"result":@"success",@"data":[storage getAllKeys]});
     }
 }
 
@@ -84,30 +82,8 @@ - (void)getItem:(NSString *)key 
callback:(WXModuleCallback)callback
         return ;
     }
     
-    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;
-            }
-        }
-    }
-    if (!value) {
-        [self executeRemoveItem:key];
-        if (callback) {
-            callback(@{@"result":@"failed",@"data":@"undefined"});
-        }
-        return;
-    }
-    [self updateTimestampForKey:key];
-    [self updateIndexForKey:key];
-    if (callback) {
-        callback(@{@"result":@"success",@"data":value});
-    }
+    id<WXStorageProtocol> storage = [self storage];
+    [storage getItem:key callback:callback];
 }
 
 - (void)setItem:(NSString *)key value:(NSString *)value 
callback:(WXModuleCallback)callback
@@ -139,7 +115,8 @@ - (void)setItem:(NSString *)key value:(NSString *)value 
callback:(WXModuleCallba
         }
         return ;
     }
-    [self setObject:value forKey:key persistent:NO callback:callback];
+    id<WXStorageProtocol> storage = [self storage];
+    [storage setObject:value forKey:key persistent:NO callback:callback];
 }
 
 - (void)setItemPersistent:(NSString *)key value:(NSString *)value 
callback:(WXModuleCallback)callback
@@ -171,7 +148,8 @@ - (void)setItemPersistent:(NSString *)key value:(NSString 
*)value callback:(WXMo
         }
         return ;
     }
-    [self setObject:value forKey:key persistent:YES callback:callback];
+    id<WXStorageProtocol> storage = [self storage];
+    [storage setObject:value forKey:key persistent:YES callback:callback];
 }
 
 - (void)removeItem:(NSString *)key callback:(WXModuleCallback)callback
@@ -193,7 +171,8 @@ - (void)removeItem:(NSString *)key 
callback:(WXModuleCallback)callback
         }
         return ;
     }
-    BOOL removed = [self executeRemoveItem:key];
+    id<WXStorageProtocol> storage = [self storage];
+    BOOL removed = [storage removeItem:key];
     if (removed) {
         if (callback) {
             callback(@{@"result":@"success"});
@@ -205,315 +184,8 @@ - (void)removeItem:(NSString *)key 
callback:(WXModuleCallback)callback
     }
 }
 
-- (BOOL)executeRemoveItem:(NSString *)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];
-        });
-    } else if (self.memory[key]) {
-        [self.memory removeObjectForKey:key];
-        NSDictionary *dict = [self.memory copy];
-        [self write:dict toFilePath:[WXStorageModule filePath]];
-    } else {
-        return NO;
-    }
-    [self removeInfoForKey:key];
-    [self removeIndexForKey:key];
-    return YES;
-}
-
-#pragma mark - Utils
-- (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;
-    }
-    
-    [[WXUtility globalCache] setObject:obj forKey:key cost:obj.length];
-    
-    if (![WXStorageNullValue isEqualToString:self.memory[key]]) {
-        self.memory[key] = WXStorageNullValue;
-        NSDictionary *dict = [self.memory copy];
-        [self write:dict toFilePath:[WXStorageModule filePath]];
-    }
-    
-    dispatch_async([WXStorageModule storageQueue], ^{
-        [obj writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding 
error:NULL];
-    });
-    
-    [self setInfo:@{@"persistent":@(persistent),@"size":@(obj.length)} 
ForKey:key];
-    [self updateIndexForKey:key];
-    
-    [self checkStorageLimit];
-    if (callback) {
-        callback(@{@"result":@"success"});
-    }
-}
-
-- (void)checkStorageLimit {
-    NSInteger size = [self totalSize] - WXStorageTotalLimit;
-    if (size > 0) {
-        [self removeItemsBySize:size];
-    }
-}
-
-- (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];
-    }
-}
-
-- (void)write:(NSDictionary *)dict toFilePath:(NSString *)filePath{
-    [dict writeToFile:filePath atomically:YES];
-}
-
-+ (NSString *)filePathForKey:(NSString *)key
-{
-    NSString *safeFileName = [WXUtility md5:key];
-    
-    return [[WXStorageModule directory] 
stringByAppendingPathComponent:safeFileName];
-}
-
-+ (void)setupDirectory{
-    BOOL isDirectory = NO;
-    BOOL fileExists = [[NSFileManager defaultManager] 
fileExistsAtPath:[WXStorageModule directory] isDirectory:&isDirectory];
-    if (!isDirectory && !fileExists) {
-        [[NSFileManager defaultManager] createDirectoryAtPath:[WXStorageModule 
directory]
-                                  withIntermediateDirectories:YES
-                                                   attributes:nil
-                                                        error:NULL];
-    }
-}
-
-+ (NSString *)directory {
-    static NSString *storageDirectory = nil;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        storageDirectory = 
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, 
YES).firstObject;
-        storageDirectory = [storageDirectory 
stringByAppendingPathComponent:WXStorageDirectory];
-    });
-    return storageDirectory;
-}
-
-+ (NSString *)filePath {
-    static NSString *storageFilePath = nil;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        storageFilePath = [[WXStorageModule directory] 
stringByAppendingPathComponent:WXStorageFileName];
-    });
-    return storageFilePath;
-}
-
-+ (NSString *)infoFilePath {
-    static NSString *infoFilePath = nil;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        infoFilePath = [[WXStorageModule directory] 
stringByAppendingPathComponent:WXStorageInfoFileName];
-    });
-    return infoFilePath;
-}
-
-+ (NSString *)indexFilePath {
-    static NSString *indexFilePath = nil;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        indexFilePath = [[WXStorageModule directory] 
stringByAppendingPathComponent:WXStorageIndexFileName];
-    });
-    return indexFilePath;
-}
-
-+ (dispatch_queue_t)storageQueue {
-    static dispatch_queue_t storageQueue;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        storageQueue = dispatch_queue_create("com.taobao.weex.storage", 
DISPATCH_QUEUE_SERIAL);
-    });
-    return storageQueue;
-}
-
-+ (WXThreadSafeMutableDictionary<NSString *, NSString *> *)memory {
-    static WXThreadSafeMutableDictionary<NSString *,NSString *> *memory;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        [WXStorageModule setupDirectory];
-        
-        if ([[NSFileManager defaultManager] fileExistsAtPath:[WXStorageModule 
filePath]]) {
-            NSDictionary *contents = [NSDictionary 
dictionaryWithContentsOfFile:[WXStorageModule filePath]];
-            if (contents) {
-                memory = [[WXThreadSafeMutableDictionary alloc] 
initWithDictionary:contents];
-            }
-        }
-        if (!memory) {
-            memory = [WXThreadSafeMutableDictionary new];
-        }
-//        [[NSNotificationCenter defaultCenter] 
addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil 
queue:nil usingBlock:^(__unused NSNotification *note) {
-//            [memory removeAllObjects];
-//        }];
-    });
-    return memory;
-}
-
-+ (WXThreadSafeMutableDictionary<NSString *, NSDictionary *> *)info {
-    static WXThreadSafeMutableDictionary<NSString *,NSDictionary *> *info;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        [WXStorageModule setupDirectory];
-        
-        if ([[NSFileManager defaultManager] fileExistsAtPath:[WXStorageModule 
infoFilePath]]) {
-            NSDictionary *contents = [NSDictionary 
dictionaryWithContentsOfFile:[WXStorageModule infoFilePath]];
-            if (contents) {
-                info = [[WXThreadSafeMutableDictionary alloc] 
initWithDictionary:contents];
-            }
-        }
-        if (!info) {
-            info = [WXThreadSafeMutableDictionary new];
-        }
-    });
-    return info;
-}
-
-+ (WXThreadSafeMutableArray *)indexs {
-    static WXThreadSafeMutableArray *indexs;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        [WXStorageModule setupDirectory];
-        
-        if ([[NSFileManager defaultManager] fileExistsAtPath:[WXStorageModule 
indexFilePath]]) {
-            NSArray *contents = [NSArray 
arrayWithContentsOfFile:[WXStorageModule indexFilePath]];
-            if (contents) {
-                indexs = [[WXThreadSafeMutableArray alloc] 
initWithArray:contents];
-            }
-        }
-        if (!indexs) {
-            indexs = [WXThreadSafeMutableArray new];
-        }
-    });
-    return indexs;
-}
-
-- (WXThreadSafeMutableDictionary<NSString *, NSString *> *)memory {
-    return [WXStorageModule memory];
-}
-
-- (WXThreadSafeMutableDictionary<NSString *, NSDictionary *> *)info {
-    return [WXStorageModule info];
-}
-
-- (WXThreadSafeMutableArray *)indexs {
-    return [WXStorageModule indexs];
-}
-
 - (BOOL)checkInput:(id)input{
     return !([input isKindOfClass:[NSString class]] || [input 
isKindOfClass:[NSNumber class]]);
 }
-
-#pragma mark
-#pragma mark - Storage Info method
-- (NSDictionary *)getInfoForKey:(NSString *)key {
-    NSDictionary *info = [[self info] objectForKey:key];
-    if (!info) {
-        return nil;
-    }
-    return info;
-}
-
-- (void)setInfo:(NSDictionary *)info ForKey:(NSString *)key {
-    NSAssert(info, @"info must not be nil");
-    
-    // save info for key
-    NSMutableDictionary *newInfo = [NSMutableDictionary 
dictionaryWithDictionary:info];
-    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
-    [newInfo setObject:@(interval) forKey:@"ts"];
-    
-    [[self info] setObject:[newInfo copy] forKey:key];
-    NSDictionary *dict = [[self info] copy];
-    [self write:dict toFilePath:[WXStorageModule infoFilePath]];
-}
-
-- (void)removeInfoForKey:(NSString *)key {
-    [[self info] removeObjectForKey:key];
-    NSDictionary *dict = [[self info] copy];
-    [self write:dict toFilePath:[WXStorageModule infoFilePath]];
-}
-
-- (void)updateTimestampForKey:(NSString *)key {
-    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
-    NSDictionary *info = [[self info] objectForKey:key];
-    if (!info) {
-        info = @{@"persistent":@(NO),@"size":@(0),@"ts":@(interval)};
-    } else {
-        NSMutableDictionary *newInfo = [NSMutableDictionary 
dictionaryWithDictionary:info];
-        [newInfo setObject:@(interval) forKey:@"ts"];
-        info = [newInfo copy];
-    }
-    
-    [[self info] setObject:info forKey:key];
-    NSDictionary *dict = [[self info] copy];
-    [self write:dict toFilePath:[WXStorageModule infoFilePath]];
-}
-
-- (NSInteger)totalSize {
-    NSInteger totalSize = 0;
-    for (NSDictionary *info in [self info].allValues) {
-        totalSize += (info[@"size"] ? [info[@"size"] integerValue] : 0);
-    }
-    return totalSize;
-}
-
-#pragma mark
-#pragma mark - Storage Index method
-- (void)updateIndexForKey:(NSString *)key {
-    [[self indexs] removeObject:key];
-    [[self indexs] addObject:key];
-    [self write:[[self indexs] copy] toFilePath:[WXStorageModule 
indexFilePath]];
-}
-
-- (void)removeIndexForKey:(NSString *)key {
-    [[self indexs] removeObject:key];
-    [self write:[[self indexs] copy] toFilePath:[WXStorageModule 
indexFilePath]];
-}
-
 @end
 
diff --git a/ios/sdk/WeexSDK/Sources/Protocol/WXStorageProtocol.h 
b/ios/sdk/WeexSDK/Sources/Protocol/WXStorageProtocol.h
new file mode 100644
index 0000000000..bda8fa5ad9
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Protocol/WXStorageProtocol.h
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "WXModuleProtocol.h"
+
+@protocol WXStorageProtocol <NSObject>
+
+- (dispatch_queue_t)targetExecuteQueue;
+
+- (NSUInteger)length;
+
+- (NSArray *)getAllKeys;
+
+- (void)getItem:(NSString *)key callback:(WXModuleCallback)callback;
+
+- (void)setObject:(NSString *)obj forKey:(NSString *)key 
persistent:(BOOL)persistent callback:(WXModuleCallback)callback;
+
+- (BOOL)removeItem:(NSString *)key;
+
+@end


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> expose handler for WXStorageModule in iOS
> -----------------------------------------
>
>                 Key: WEEX-213
>                 URL: https://issues.apache.org/jira/browse/WEEX-213
>             Project: Weex
>          Issue Type: Improvement
>            Reporter: Hao Junhua
>            Assignee: Adam Feng
>            Priority: Major
>
> Android has done this feature



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to