You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ji...@apache.org on 2017/01/24 08:18:26 UTC

[11/50] [abbrv] incubator-weex git commit: + [ios] iOS init.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
new file mode 100644
index 0000000..79f587f
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
@@ -0,0 +1,282 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import "WXDefine.h"
+#import "WXType.h"
+#import "WXLog.h"
+
+// The default screen width which helps us to caculate the real size or scale in different devices.
+static const CGFloat WXDefaultScreenWidth = 750.0;
+
+#define WX_ENUMBER_CASE(_invoke, idx, code, obj, _type, op, _flist) \
+case code:{\
+    _type *_tmp = malloc(sizeof(_type));\
+    memset(_tmp, 0, sizeof(_type));\
+    *_tmp = [obj op];\
+    [_invoke setArgument:_tmp atIndex:(idx) + 2];\
+    *(_flist + idx) = _tmp;\
+    break;\
+}
+#define WX_EPCHAR_CASE(_invoke, idx, code, obj, _type, op, _flist) \
+case code:{\
+    _type *_tmp = (_type  *)[obj op];\
+    [_invoke setArgument:&_tmp atIndex:(idx) + 2];\
+    *(_flist + idx) = 0;\
+    break;\
+}\
+
+#define WX_ALLOC_FLIST(_ppFree, _count) \
+do {\
+    _ppFree = (void *)malloc(sizeof(void *) * (_count));\
+    memset(_ppFree, 0, sizeof(void *) * (_count));\
+} while(0)
+
+#define WX_FREE_FLIST(_ppFree, _count) \
+do {\
+    for(int i = 0; i < _count; i++){\
+        if(*(_ppFree + i ) != 0) {\
+            free(*(_ppFree + i));\
+        }\
+    }\
+    free(_ppFree);\
+}while(0)
+
+#define WX_ARGUMENTS_SET(_invocation, _sig, idx, _obj, _ppFree) \
+do {\
+    const char *encode = [_sig getArgumentTypeAtIndex:(idx) + 2];\
+    switch(encode[0]){\
+        WX_EPCHAR_CASE(_invocation, idx, _C_CHARPTR, _obj, char *, UTF8String, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_INT, _obj, int, intValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_SHT, _obj, short, shortValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_LNG, _obj, long, longValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_LNG_LNG, _obj, long long, longLongValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_UCHR, _obj, unsigned char, unsignedCharValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_UINT, _obj, unsigned int, unsignedIntValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_USHT, _obj, unsigned short, unsignedShortValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_ULNG, _obj, unsigned long, unsignedLongValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_ULNG_LNG, _obj,unsigned long long, unsignedLongLongValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_FLT, _obj, float, floatValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_DBL, _obj, double, doubleValue, _ppFree)\
+        WX_ENUMBER_CASE(_invocation, idx, _C_BOOL, _obj, bool, boolValue, _ppFree)\
+        default: { [_invocation setArgument:&_obj atIndex:(idx) + 2]; *(_ppFree + idx) = 0; break;}\
+    }\
+}while(0)
+
+/**
+ * @abstract execute asynchronous action block on the main thread.
+ *
+ */
+extern void WXPerformBlockOnMainThread( void (^ _Nonnull block)());
+
+/**
+ * @abstract execute synchronous action block on the main thread.
+ *
+ */
+extern void WXPerformBlockSyncOnMainThread( void (^ _Nonnull block)());
+
+/**
+ * @abstract swizzling methods.
+ *
+ */
+extern void WXSwizzleInstanceMethod(_Nonnull Class class, _Nonnull SEL original, _Nonnull SEL replaced);
+
+extern void WXSwizzleInstanceMethodWithBlock(_Nonnull Class class, _Nonnull SEL original, _Nonnull id block, _Nonnull SEL replaced);
+
+extern _Nonnull SEL WXSwizzledSelectorForSelector(_Nonnull SEL selector);
+
+@interface WXUtility : NSObject
+
+/**
+ * @abstract Returns the environment of current application, you can get some nessary properties such as appVersion\u3001sdkVersion\u3001appName etc.
+ *
+ * @return A dictionary object which contains these properties.
+ *
+ */
++ (NSDictionary *_Nonnull)getEnvironment;
+
+/**
+ * @abstract UserAgent Generation
+ *
+ * @return A ua string by splicing (deviceName\u3001appVersion\u3001sdkVersion\u3001externalField\u3001screenSize)
+ *
+ */
++ (NSString *_Nonnull)userAgent;
+
+/**
+ * @abstract JSON Decode Mehthod
+ *
+ * @param JSON String.
+ *
+ * @return A json object by decoding json string.
+ *
+ */
++ (id _Nullable)objectFromJSON:(NSString * _Nonnull)json;
+
+#define WXDecodeJson(json)  [WXUtility objectFromJSON:json]
+
+/**
+ * @abstract JSON Encode Mehthod
+ *
+ * @param JSON Object.
+ *
+ * @return A json string by encoding json object.
+ *
+ */
++ (NSString * _Nullable)JSONString:(id _Nonnull)object;
+
+#define WXEncodeJson(obj)  [WXUtility JSONString:obj]
+
+/**
+ * @abstract JSON Object Copy Mehthod
+ *
+ * @param JSON Object.
+ *
+ * @return A json object by copying.
+ *
+ */
++ (id _Nullable)copyJSONObject:(id _Nonnull)object;
+
+#define WXCopyJson(obj)     [WXUtility copyJSONObject:obj]
+
+/**
+ *
+ *  Checks if a String is whitespace, empty ("") or nil
+ *  @code
+ *    [WXUtility isBlankString: nil]       = true
+ *    [WXUtility isBlankString: ""]        = true
+ *    [WXUtility isBlankString: " "]       = true
+ *    [WXUtility isBlankString: "bob"]     = false
+ *    [WXUtility isBlankString: "  bob  "] = false
+ *  @endcode
+ *  @param string the String to check, may be null
+ *
+ *  @return true if the String is null, empty or whitespace
+ */
++ (BOOL)isBlankString:(NSString * _Nullable)string ;
+
+/**
+ * @abstract Returns a standard error object
+ *
+ * @param error code.
+ *
+ * @param error message.
+ *
+ * @return A error object type of NSError.
+ *
+ */
++ (NSError * _Nonnull)errorWithCode:(NSInteger)code message:(NSString * _Nullable)message;
+
+/**
+ * @abstract Returns a Font Object by setting some properties such as size\u3001weight\u3001style and fontFamily.
+ *
+ * @param textSize.
+ *
+ * @param textWeight. The type of WXTextWeight (Normal or Bold).
+ *
+ * @param textStyle. The type of WXTextStyle (Normal or Italic).
+ *
+ * @param fontFamily.
+ *
+ * @return A font object according to the above params.
+ *
+ */
++ (UIFont *_Nonnull)fontWithSize:(CGFloat)size textWeight:(WXTextWeight)textWeight textStyle:(WXTextStyle)textStyle fontFamily:(NSString *_Nullable)fontFamily;
+
+/**
+ * @abstract Returns the scale of the main screen.
+ *
+ */
+CGFloat WXScreenScale();
+
+/**
+ * @abstract Returns the metrics of the main screen.
+ *
+ */
+CGSize WXScreenSize();
+
+/**
+ * @abstract Returns the resize radio of the main screen. 
+ *
+ * @discussion If orientation is equal to landscape, the value is caculated as follows: WXScreenSize().height / WXDefaultScreenWidth, otherwise, WXScreenSize().width / WXDefaultScreenWidth.
+ *
+ */
+CGFloat WXScreenResizeRadio(void);
+
+/**
+ * @abstract Returns a Round float coordinates to the main screen pixel.
+ *
+ */
+CGFloat WXRoundPixelValue(CGFloat value);
+
+/**
+ * @abstract Returns a Floor float coordinates to the main screen pixel.
+ *
+ */
+CGFloat WXFloorPixelValue(CGFloat value);
+
+/**
+ * @abstract Returns a Ceil float coordinates to the main screen pixel.
+ *
+ */
+CGFloat WXCeilPixelValue(CGFloat value);
+
+/**
+ *  @abstract Returns a resized pixel which is caculated according to the WXScreenResizeRadio.
+ *
+ */
+CGFloat WXPixelResize(CGFloat value);
+
+/**
+ *  @abstract Returns a resized frame which is caculated according to the WXScreenResizeRadio.
+ *
+ */
+CGRect WXPixelFrameResize(CGRect value);
+
+/**
+ *  @abstract Returns a resized point which is caculated according to the WXScreenResizeRadio.
+ *
+ */
+CGPoint WXPixelPointResize(CGPoint value);
+
+/**
+ *  @abstract Returns the document directory path.
+ *
+ */
++ (NSString *_Nonnull)documentDirectory;
+
+#define WXDocumentPath     [WXUtility documentDirectory]
+
+/**
+ *  @abstract Returns the system cache directory path.
+ *
+ */
++ (NSString *_Nonnull)cacheDirectory;
+
+#define WXCachePath     [WXUtility cacheDirectory]
+
+/**
+ *  @abstract Returns the system library directory path.
+ *
+ */
++ (NSString *_Nonnull)libraryDirectory;
+
+#define WXLibararyPath  [WXUtility libraryDirectory]
+
+/**
+ *  @abstract Returns the global cache whose size is 5M.
+ *
+ */
++ (NSCache *_Nonnull)globalCache;
+
+#define WXGlobalCache   [WXUtility globalCache]
+
++ (void)addStatTrack:(NSString *_Nonnull)appName;
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
new file mode 100644
index 0000000..21bdd9f
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
@@ -0,0 +1,389 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXUtility.h"
+#import "WXLog.h"
+#import "WXSDKEngine.h"
+#import "WXAppConfiguration.h"
+#import <objc/runtime.h>
+#import <objc/message.h>
+#import <sys/utsname.h>
+#import <UIKit/UIScreen.h>
+
+void WXPerformBlockOnMainThread(void (^ _Nonnull block)())
+{
+    if ([NSThread isMainThread]) {
+        block();
+    } else {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            block();
+        });
+    }
+}
+
+void WXPerformBlockSyncOnMainThread(void (^ _Nonnull block)())
+{
+    if ([NSThread isMainThread]) {
+        block();
+    } else {
+        dispatch_sync(dispatch_get_main_queue(), ^{
+            block();
+        });
+    }
+}
+
+void WXSwizzleInstanceMethod(Class class, SEL original, SEL replaced)
+{
+    Method originalMethod = class_getInstanceMethod(class, original);
+    Method newMethod = class_getInstanceMethod(class, replaced);
+    
+    BOOL didAddMethod = class_addMethod(class, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
+    if (didAddMethod) {
+        class_replaceMethod(class, replaced, method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
+    } else {
+        method_exchangeImplementations(originalMethod, newMethod);
+    }
+}
+
+void WXSwizzleInstanceMethodWithBlock(Class class, SEL original, id block, SEL replaced)
+{
+    Method originalMethod = class_getInstanceMethod(class, original);
+    IMP implementation = imp_implementationWithBlock(block);
+    
+    class_addMethod(class, replaced, implementation, method_getTypeEncoding(originalMethod));
+    Method newMethod = class_getInstanceMethod(class, replaced);
+    method_exchangeImplementations(originalMethod, newMethod);
+}
+
+SEL WXSwizzledSelectorForSelector(SEL selector)
+{
+    return NSSelectorFromString([NSString stringWithFormat:@"wx_swizzle_%x_%@", arc4random(), NSStringFromSelector(selector)]);
+}
+
+CGFloat WXScreenScale(void)
+{
+    static CGFloat _scale;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _scale = [UIScreen mainScreen].scale;
+    });
+    return _scale;
+}
+
+CGSize WXScreenSize(void)
+{
+    return [UIScreen mainScreen].bounds.size;
+}
+
+CGFloat WXScreenResizeRadio(void)
+{
+    static CGFloat resizeScale;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        CGSize size = WXScreenSize();
+        CGFloat deviceWidth;
+        if (size.width > size.height) {
+            // Landscape
+            deviceWidth = size.height;
+        } else {
+            deviceWidth = size.width;
+        }
+        
+        resizeScale = deviceWidth / WXDefaultScreenWidth;
+    });
+    
+    return resizeScale;
+}
+
+CGFloat WXRoundPixelValue(CGFloat value)
+{
+    CGFloat scale = WXScreenScale();
+    return round(value * scale) / scale;
+}
+
+CGFloat WXCeilPixelValue(CGFloat value)
+{
+    CGFloat scale = WXScreenScale();
+    return ceil(value * scale) / scale;
+}
+
+CGFloat WXFloorPixelValue(CGFloat value)
+{
+    CGFloat scale = WXScreenScale();
+    return floor(value * scale) / scale;
+}
+
+CGFloat WXPixelResize(CGFloat value)
+{
+    return WXCeilPixelValue(value * WXScreenResizeRadio());
+}
+
+CGRect WXPixelFrameResize(CGRect value)
+{
+    CGRect new = CGRectMake(value.origin.x * WXScreenResizeRadio(),
+                            value.origin.y * WXScreenResizeRadio(),
+                            value.size.width * WXScreenResizeRadio(),
+                            value.size.height * WXScreenResizeRadio());
+    return new;
+}
+
+CGPoint WXPixelPointResize(CGPoint value)
+{
+    CGPoint new = CGPointMake(value.x * WXScreenResizeRadio(),
+                              value.y * WXScreenResizeRadio());
+    return new;
+}
+
+@implementation WXUtility
+
++ (NSDictionary *)getEnvironment
+{
+    NSString *platform = @"iOS";
+    NSString *sysVersion = [[UIDevice currentDevice] systemVersion];
+    NSString *weexVersion = WX_SDK_VERSION;
+    NSString *machine = [self deviceName] ? : @"";
+    NSString *appVersion = [WXAppConfiguration appVersion] ? : @"";
+    NSString *appName = [WXAppConfiguration appName] ? : @"";
+    
+    CGFloat deviceWidth = [[UIScreen mainScreen] bounds].size.width;
+    CGFloat deviceHeight = [[UIScreen mainScreen] bounds].size.height;
+    CGFloat scale = [[UIScreen mainScreen] scale];
+    
+    NSMutableDictionary *data = [NSMutableDictionary dictionaryWithDictionary:@{
+                                    @"platform":platform,
+                                    @"osVersion":sysVersion,
+                                    @"weexVersion":weexVersion,
+                                    @"deviceModel":machine,
+                                    @"appName":appName,
+                                    @"appVersion":appVersion,
+                                    @"deviceWidth":@(deviceWidth * scale),
+                                    @"deviceHeight":@(deviceHeight * scale),
+                                    @"scale":@(scale),
+                                    @"logLevel":[WXLog logLevelString]
+                                }];
+    return data;
+}
+
++ (NSString *)userAgent
+{
+    // Device UA
+    NSString *deviceUA = [NSString stringWithFormat:@"%@(iOS/%@)", [self deviceName]?:@"UNKNOWN", [[UIDevice currentDevice] systemVersion]]?:@"0.0.0";
+    
+    // App UA
+    NSString *appUA = [NSString stringWithFormat:@"%@(%@/%@)", [WXAppConfiguration appGroup]?:@"WeexGroup", [WXAppConfiguration appName]?:@"WeexApp", [WXAppConfiguration appVersion]?:@"0.0.0"];
+
+    // Weex UA
+    NSString *weexUA = [NSString stringWithFormat:@"Weex/%@", WX_SDK_VERSION];
+    
+    // external UA
+    NSString *externalUA = [WXAppConfiguration externalUserAgent] ? [NSString stringWithFormat:@" %@", [WXAppConfiguration externalUserAgent]] : @"";
+    
+    // Screen Size
+    CGFloat w = [[UIScreen mainScreen] bounds].size.width;
+    CGFloat h = [[UIScreen mainScreen] bounds].size.height;
+    CGFloat s = [[UIScreen mainScreen] scale];
+    NSString * screenUA = [NSString stringWithFormat:@"%dx%d", (int)(s * w), (int)(s * h)];
+    
+    // New UA
+    return [NSString stringWithFormat:@"%@ %@ %@%@ %@", deviceUA, appUA, weexUA, externalUA, screenUA];
+}
+
++ (id)objectFromJSON:(NSString *)json
+{
+    if (!json) return nil;
+    
+    NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
+    NSError *error = nil;
+    id obj = [NSJSONSerialization JSONObjectWithData:data
+                                             options:NSJSONReadingAllowFragments | NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves
+                                               error:&error];
+    if(error){
+        WXLogError(@"%@", [error description]);
+        return nil;
+    }
+    
+    return obj;
+}
+
++ (NSString *)JSONString:(id)object
+{
+    if(!object) return nil;
+    
+    NSError *error = nil;
+    if([object isKindOfClass:[NSArray class]] || [object isKindOfClass:[NSDictionary class]]){
+        NSData *data = [NSJSONSerialization dataWithJSONObject:object
+                                                       options:NSJSONWritingPrettyPrinted
+                                                         error:&error];
+        if (error) {
+            WXLogError(@"%@", [error description]);
+            return nil;
+        }
+        
+        return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+    
+    } else if ([object isKindOfClass:[NSString class]]) {
+        NSArray *array = @[object];
+        NSData *data = [NSJSONSerialization dataWithJSONObject:array
+                                                       options:NSJSONWritingPrettyPrinted
+                                                         error:&error];
+        if (error) {
+            WXLogError(@"%@", [error description]);
+            return nil;
+        }
+        
+        NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+        if (string.length <= 4) {
+            WXLogError(@"json convert length less than 4 chars.");
+            return nil;
+        }
+        
+        return [string substringWithRange:NSMakeRange(2, string.length - 4)];
+    } else {
+        WXLogError(@"object isn't avaliable class");
+        return nil;
+    }
+}
+
++ (id)copyJSONObject:(id)object
+{
+    if ([object isKindOfClass:[NSArray class]]) {
+        NSArray *array = (NSArray *)object;
+        NSMutableArray *copyObjs = [NSMutableArray array];
+        
+        [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+            id copyObj = [self copyJSONObject:obj];
+            [copyObjs insertObject:copyObj atIndex:idx];
+        }];
+        
+        return copyObjs;
+    } else if ([object isKindOfClass:[NSDictionary class]]) {
+        NSDictionary *dict = (NSDictionary *)object;
+        NSMutableDictionary *copyObjs = [NSMutableDictionary dictionary];
+        
+        [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+            id copyObj = [self copyJSONObject:obj];
+            [copyObjs setObject:copyObj forKey:key];
+        }];
+        
+        return copyObjs;
+    } else {
+        return [object copy];
+    }
+}
+
++ (BOOL)isBlankString:(NSString *)string {
+    if (string == nil || string == NULL || [string isKindOfClass:[NSNull class]]) {
+        return true;
+    }
+    if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
+        return true;
+    }
+    
+    return false;
+}
+
++ (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message
+{
+    message = message ? : @"";
+    return [NSError errorWithDomain:@"WeexErrorDomain" code:code userInfo:@{@"errMsg":message}];
+}
+
++ (UIFont *)fontWithSize:(CGFloat)size textWeight:(WXTextWeight)textWeight textStyle:(WXTextStyle)textStyle fontFamily:(NSString *)fontFamily
+{
+    CGFloat fontSize = (isnan(size) || size == 0) ?  WX_TEXT_FONT_SIZE : size;
+    UIFont *font;
+    
+    if (fontFamily) {
+        font = [UIFont fontWithName:fontFamily size:fontSize];
+        if (!font) {
+            WXLogWarning(@"Unknown fontFamily:%@", fontFamily);
+            font = [UIFont systemFontOfSize:fontSize];
+        }
+    } else {
+        font = [UIFont systemFontOfSize:fontSize];
+    }
+    
+    UIFontDescriptor *fontD = font.fontDescriptor;
+    UIFontDescriptorSymbolicTraits traits = 0;
+    traits = (textStyle == WXTextStyleItalic) ? (traits | UIFontDescriptorTraitItalic) : traits;
+    traits = (textWeight == WXTextWeightBold) ? (traits | UIFontDescriptorTraitBold) : traits;
+    fontD = [fontD fontDescriptorWithSymbolicTraits:traits];
+    font = [UIFont fontWithDescriptor:fontD size:0];
+    
+    return font;
+}
+
++ (NSString *)documentDirectory
+{
+    static NSString *docPath = nil;
+    if (!docPath){
+        docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
+    }
+    return docPath;
+}
+
++ (NSString *)cacheDirectory
+{
+    static NSString *cachePath = nil;
+    if (!cachePath) {
+        cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
+    }
+    return cachePath;
+}
+
++ (NSString *)libraryDirectory
+{
+    static NSString *libPath = nil;
+    if (!libPath) {
+        libPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject;
+    }
+    return libPath;
+}
+
++ (NSCache *)globalCache
+{
+    static NSCache *cache;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        cache = [NSCache new];
+        cache.totalCostLimit = 5 * 1024 * 1024;
+        
+        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(__unused NSNotification *note) {
+            [cache removeAllObjects];
+        }];
+    });
+    return cache;
+}
+
++ (NSString *)deviceName
+{
+    struct utsname systemInfo;
+    uname(&systemInfo);
+    return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
+}
+
++ (void)addStatTrack:(NSString *)appName
+{
+    if (!appName) {
+        return;
+    }
+    
+    // App name for non-commercial use
+    NSString *urlString = [NSString stringWithFormat:@"http://gm.mmstat.com/weex.1003?appname=%@", appName];
+    NSURL *URL = [NSURL URLWithString:urlString];
+    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
+    
+    NSURLSession *session = [NSURLSession sharedSession];
+    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
+                                            completionHandler:
+                                  ^(NSData *data, NSURLResponse *response, NSError *error) {
+                                  }];
+    [task resume];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.h b/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.h
new file mode 100644
index 0000000..2e90fe4
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.h
@@ -0,0 +1,17 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface WXWeakObjectWrapper : NSObject
+
+@property (nonatomic, weak, readonly) id weakObject;
+
+- (id)initWithWeakObject:(id)weakObject;
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.m b/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.m
new file mode 100644
index 0000000..f807b00
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXWeakObjectWrapper.m
@@ -0,0 +1,22 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXWeakObjectWrapper.h"
+
+@implementation WXWeakObjectWrapper
+
+- (id)initWithWeakObject:(id)weakObject
+{
+    if (self = [super init]) {
+        _weakObject = weakObject;
+    }
+    
+    return self;
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.h b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.h
new file mode 100644
index 0000000..f1d436d
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.h
@@ -0,0 +1,13 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import <WeexSDK/WeexSDK.h>
+
+@interface WXComponent (ViewManangement)
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.m b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.m
new file mode 100644
index 0000000..93df38b
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManangement.m
@@ -0,0 +1,254 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXComponent+ViewManangement.h"
+#import "WXComponent_internal.h"
+#import "WXAssert.h"
+#import "WXView.h"
+#import "WXSDKInstance_private.h"
+#import "WXTransform.h"
+
+#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
+
+@implementation WXComponent (ViewManangement)
+
+#pragma mark Public
+
+- (UIView *)loadView
+{
+    return [[WXView alloc] init];
+}
+
+- (BOOL)isViewLoaded
+{
+    return (_view != nil);
+}
+
+- (UIView *)view
+{
+    if ([self isViewLoaded]) {
+        return _view;
+    } else {
+        WXAssertMainThread();
+        
+        // compositing child will be drew by its composited ancestor
+        if (_compositingChild) {
+            return nil;
+        }
+        
+        [self viewWillLoad];
+        
+        _view = [self loadView];
+        
+        _layer = _view.layer;
+        _view.frame = _calculatedFrame;
+        
+        _view.hidden = _visibility == WXVisibilityShow ? NO : YES;
+        _view.clipsToBounds = _clipToBounds;
+        
+        if (![self _needsDrawBorder]) {
+            _layer.borderColor = _borderTopColor.CGColor;
+            _layer.borderWidth = _borderTopWidth;
+            _layer.cornerRadius = _borderTopLeftRadius;
+            _layer.opacity = _opacity;
+            _view.backgroundColor = _backgroundColor;
+        }
+        
+        _view.wx_component = self;
+        _layer.wx_component = self;
+        
+        [self _initEvents:self.events];
+        
+        if (_positionType == WXPositionTypeSticky) {
+            [self.ancestorScroller addStickyComponent:self];
+        }
+        
+        if (self.supercomponent && self.supercomponent->_async) {
+            self->_async = YES;
+        }
+        
+        [self setNeedsDisplay];
+        [self viewDidLoad];
+        
+        if (_lazyCreateView) {
+            if (self.supercomponent && !((WXComponent *)self.supercomponent)->_lazyCreateView) {
+                NSInteger index = [((WXComponent *)self.supercomponent).subcomponents indexOfObject:self];
+                if (index != NSNotFound) {
+                    [((WXComponent *)self.supercomponent) insertSubview:self atIndex:index];
+                }
+            }
+            for (WXComponent *subcomponent in self.subcomponents) {
+                [self.view addSubview:subcomponent.view];
+            }
+        }
+        
+        return _view;
+    }
+}
+
+- (CALayer *)layer
+{
+    return _layer;
+}
+
+- (void)insertSubview:(WXComponent *)subcomponent atIndex:(NSInteger)index
+{
+    WXAssertMainThread();
+    
+    if (subcomponent->_positionType == WXPositionTypeFixed) {
+        [self.weexInstance.rootView addSubview:subcomponent.view];
+        return;
+    }
+    
+    // use _lazyCreateView to forbid component like cell's view creating
+    if(_lazyCreateView) {
+        subcomponent->_lazyCreateView = YES;
+    }
+    
+    if (!subcomponent->_lazyCreateView || (self->_lazyCreateView && [self isViewLoaded])) {
+        [self.view insertSubview:subcomponent.view atIndex:index];
+    }
+}
+
+- (void)removeFromSuperview
+{
+    WXAssertMainThread();
+    
+    if ([self isViewLoaded]) {
+        [self.view removeFromSuperview];
+    }
+}
+
+- (void)moveToSuperview:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index
+{
+    [self removeFromSuperview];
+    [newSupercomponent insertSubview:self atIndex:index];
+}
+
+- (void)viewWillLoad
+{
+    WXAssertMainThread();
+}
+
+- (void)viewDidLoad
+{
+    WXAssertMainThread();
+}
+
+- (void)viewWillUnload
+{
+    WXAssertMainThread();
+}
+
+- (void)viewDidUnload
+{
+    WXAssertMainThread();
+}
+
+#pragma mark Private
+
+- (void)_initViewPropertyWithStyles:(NSDictionary *)styles
+{
+    _backgroundColor = styles[@"backgroundColor"] ? [WXConvert UIColor:styles[@"backgroundColor"]] : [UIColor clearColor];
+    _opacity = styles[@"opacity"] ? [WXConvert CGFloat:styles[@"opacity"]] : 1.0;
+    _clipToBounds = styles[@"overflow"] ? [WXConvert WXClipType:styles[@"overflow"]] : NO;
+    _visibility = styles[@"visibility"] ? [WXConvert WXVisibility:styles[@"visibility"]] : WXVisibilityShow;
+    _positionType = styles[@"position"] ? [WXConvert WXPositionType:styles[@"position"]] : WXPositionTypeRelative;
+    _transform = styles[@"transform"] ? [WXConvert NSString:styles[@"transform"]] : nil;
+    _transformOrigin = styles[@"transformOrigin"] ? [WXConvert NSString:styles[@"transformOrigin"]] : nil;
+}
+
+- (void)_updateViewStyles:(NSDictionary *)styles
+{
+    if (styles[@"backgroundColor"]) {
+        _backgroundColor = [WXConvert UIColor:styles[@"backgroundColor"]];
+        _layer.backgroundColor = _backgroundColor.CGColor;
+        [self setNeedsDisplay];
+    }
+    
+    if (styles[@"opacity"]) {
+        _opacity = [WXConvert CGFloat:styles[@"opacity"]];
+        _layer.opacity = _opacity;
+    }
+    
+    if (styles[@"overflow"]) {
+        _clipToBounds = [WXConvert WXClipType:styles[@"overflow"]];
+        _view.clipsToBounds = _clipToBounds;
+    }
+    
+    if (styles[@"position"]) {
+        WXPositionType positionType = [WXConvert WXPositionType:styles[@"position"]];
+        if (positionType == WXPositionTypeSticky) {
+            [self.ancestorScroller addStickyComponent:self];
+        } else if (_positionType == WXPositionTypeSticky) {
+            [self.ancestorScroller removeStickyComponent:self];
+        }
+        
+        if (positionType == WXPositionTypeFixed) {
+            [self.weexInstance.componentManager addFixedComponent:self];
+            _isNeedJoinLayoutSystem = NO;
+        } else if (_positionType == WXPositionTypeFixed) {
+            [self.weexInstance.componentManager removeFixedComponent:self];
+            _isNeedJoinLayoutSystem = YES;
+        }
+        
+        _positionType = positionType;
+    }
+    
+    if (styles[@"visibility"]) {
+        _visibility = [WXConvert WXVisibility:styles[@"visibility"]];
+        if (_visibility == WXVisibilityShow) {
+            self.view.hidden = NO;
+        }
+        else {
+            self.view.hidden = YES;
+        }
+    }
+    
+    if (styles[@"transformOrigin"]) {
+        _transformOrigin = [WXConvert NSString:styles[@"transformOrigin"]];
+    }
+    
+    if (styles[@"transform"]) {
+        if (!CGRectEqualToRect(self.calculatedFrame, CGRectZero)) {
+            _transform = [WXConvert NSString:styles[@"transform"]];
+            _layer.transform = [[WXTransform new] getTransform:_transform withView:_view withOrigin:_transformOrigin];
+            [_layer setNeedsDisplay];
+        }
+    }
+}
+
+- (void)_unloadView
+{
+    WXAssertMainThread();
+    
+    [self viewWillUnload];
+    
+    [_view removeFromSuperview];
+    [_layer removeFromSuperlayer];
+    
+    _view.gestureRecognizers = nil;
+    
+    [self _removeAllEvents];
+    
+    if(self.ancestorScroller){
+        [self.ancestorScroller removeStickyComponent:self];
+        [self.ancestorScroller removeScrollToListener:self];
+    }
+    
+    for (WXComponent *subcomponents in self.subcomponents) {
+        [subcomponents _unloadView];
+    }
+    
+    _view = nil;
+    _layer = nil;
+    
+    [self viewDidUnload];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/View/WXView.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/View/WXView.h b/ios/sdk/WeexSDK/Sources/View/WXView.h
new file mode 100644
index 0000000..c81c9f8
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/View/WXView.h
@@ -0,0 +1,13 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface WXView : UIView
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/View/WXView.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/View/WXView.m b/ios/sdk/WeexSDK/Sources/View/WXView.m
new file mode 100644
index 0000000..de848f9
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/View/WXView.m
@@ -0,0 +1,49 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXView.h"
+#import "WXComponent.h"
+#import "WXLayer.h"
+
+@implementation WXView
+
++ (Class)layerClass
+{
+    return [WXLayer class];
+}
+
+- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
+{
+    /**
+     *  Capturing touches on a subview outside the frame of its superview
+     */
+
+    // hidden view should not be passed event
+    if (self.hidden) {
+        return nil;
+    }
+    
+    UIView* result = [super hitTest:point withEvent:event];
+    if (result) {
+        return result;
+    }
+    
+    for (UIView* subView in [self.subviews reverseObjectEnumerator]) {
+        if (subView.hidden) {
+            continue;
+        }
+        CGPoint subPoint = [self convertPoint:point toView:subView];
+        result = [subView hitTest:subPoint withEvent:event];
+        if (result) {
+            return result;
+        }
+    }
+    
+    return nil;
+}
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/WeexSDK.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/WeexSDK.h b/ios/sdk/WeexSDK/Sources/WeexSDK.h
new file mode 100644
index 0000000..00cf605
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/WeexSDK.h
@@ -0,0 +1,31 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ * 
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#ifdef __OBJC__
+
+#import "Layout.h"
+#import "WXAppConfiguration.h"
+#import "WXAppMonitorProtocol.h"
+#import "WXBaseViewController.h"
+#import "WXComponent.h"
+#import "WXConvert.h"
+#import "WXDebugTool.h"
+#import "WXDefine.h"
+#import "WXEventModuleProtocol.h"
+#import "WXImgLoaderProtocol.h"
+#import "WXLog.h"
+#import "WXModuleProtocol.h"
+#import "WXNavigationProtocol.h"
+#import "WXNetworkProtocol.h"
+#import "WXRootViewController.h"
+#import "WXSDKEngine.h"
+#import "WXSDKInstance.h"
+#import "WXType.h"
+#import "WXUtility.h"
+
+#endif /* __OBJC__ */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/dependency/SRWebSocket.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/dependency/SRWebSocket.h b/ios/sdk/WeexSDK/dependency/SRWebSocket.h
new file mode 100644
index 0000000..5f8bca1
--- /dev/null
+++ b/ios/sdk/WeexSDK/dependency/SRWebSocket.h
@@ -0,0 +1,140 @@
+//
+//   Copyright 2012 Square Inc.
+//
+//   Licensed 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 <Security/SecCertificate.h>
+
+typedef NS_ENUM(NSInteger, SRReadyState) {
+    SR_CONNECTING   = 0,
+    SR_OPEN         = 1,
+    SR_CLOSING      = 2,
+    SR_CLOSED       = 3,
+};
+
+typedef enum SRStatusCode : NSInteger {
+    SRStatusCodeNormal = 1000,
+    SRStatusCodeGoingAway = 1001,
+    SRStatusCodeProtocolError = 1002,
+    SRStatusCodeUnhandledType = 1003,
+    // 1004 reserved.
+    SRStatusNoStatusReceived = 1005,
+    // 1004-1006 reserved.
+    SRStatusCodeInvalidUTF8 = 1007,
+    SRStatusCodePolicyViolated = 1008,
+    SRStatusCodeMessageTooBig = 1009,
+} SRStatusCode;
+
+@class SRWebSocket;
+
+extern NSString *const SRWebSocketErrorDomain;
+extern NSString *const SRHTTPResponseErrorKey;
+
+#pragma mark - SRWebSocketDelegate
+
+@protocol SRWebSocketDelegate;
+
+#pragma mark - SRWebSocket
+
+@interface SRWebSocket : NSObject <NSStreamDelegate>
+
+@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;
+
+@property (nonatomic, readonly) SRReadyState readyState;
+@property (nonatomic, readonly, retain) NSURL *url;
+
+
+@property (nonatomic, readonly) CFHTTPMessageRef receivedHTTPHeaders;
+
+// Optional array of cookies (NSHTTPCookie objects) to apply to the connections
+@property (nonatomic, readwrite) NSArray * requestCookies;
+
+// This returns the negotiated protocol.
+// It will be nil until after the handshake completes.
+@property (nonatomic, readonly, copy) NSString *protocol;
+
+// Protocols should be an array of strings that turn into Sec-WebSocket-Protocol.
+- (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;
+- (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols;
+- (id)initWithURLRequest:(NSURLRequest *)request;
+
+// Some helper constructors.
+- (id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;
+- (id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols;
+- (id)initWithURL:(NSURL *)url;
+
+// Delegate queue will be dispatch_main_queue by default.
+// You cannot set both OperationQueue and dispatch_queue.
+- (void)setDelegateOperationQueue:(NSOperationQueue*) queue;
+- (void)setDelegateDispatchQueue:(dispatch_queue_t) queue;
+
+// By default, it will schedule itself on +[NSRunLoop SR_networkRunLoop] using defaultModes.
+- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;
+- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;
+
+// SRWebSockets are intended for one-time-use only.  Open should be called once and only once.
+- (void)open;
+
+- (void)close;
+- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason;
+
+// Send a UTF8 String or Data.
+- (void)send:(id)data;
+
+// Send Data (can be nil) in a ping message.
+- (void)sendPing:(NSData *)data;
+
+@end
+
+#pragma mark - SRWebSocketDelegate
+
+@protocol SRWebSocketDelegate <NSObject>
+
+// message will either be an NSString if the server is using text
+// or NSData if the server is using binary.
+- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
+
+@optional
+
+- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
+- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
+- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
+- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;
+
+@end
+
+#pragma mark - NSURLRequest (CertificateAdditions)
+
+@interface NSURLRequest (CertificateAdditions)
+
+@property (nonatomic, retain, readonly) NSArray *SR_SSLPinnedCertificates;
+
+@end
+
+#pragma mark - NSMutableURLRequest (CertificateAdditions)
+
+@interface NSMutableURLRequest (CertificateAdditions)
+
+@property (nonatomic, retain) NSArray *SR_SSLPinnedCertificates;
+
+@end
+
+#pragma mark - NSRunLoop (SRWebSocket)
+
+@interface NSRunLoop (SRWebSocket)
+
++ (NSRunLoop *)SR_networkRunLoop;
+
+@end