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:28 UTC

[13/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/Model/WXComponent.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.h b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
new file mode 100644
index 0000000..5682e80
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.h
@@ -0,0 +1,310 @@
+/**
+ * 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 "Layout.h"
+@class WXSDKInstance;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface WXComponent : NSObject
+
+///--------------------------------------
+/// @name Component Hierarchy Management
+///--------------------------------------
+
+/**
+ *  @abstract Initializes a new component using the specified  properties.
+ *
+ *  @param ref          the identity string of component
+ *  @param type         component type
+ *  @param styles       component's styles
+ *  @param attributes   component's attributes
+ *  @param events       component's events
+ *  @param weexInstance the weexInstance with which the component associated
+ *
+ *  @return A WXComponent instance.
+ */
+- (instancetype)initWithRef:(NSString *)ref
+                       type:(NSString*)type
+                     styles:(nullable NSDictionary *)styles
+                 attributes:(nullable NSDictionary *)attributes
+                     events:(nullable NSArray *)events
+               weexInstance:(WXSDKInstance *)weexInstance;
+
+/**
+ *  @abstract The component's identifier string.
+ */
+@property (nonatomic, readonly, strong) NSString *ref;
+
+/**
+ *  @abstract The component's styles.
+ */
+@property (nonatomic, readonly, strong) NSDictionary *styles;
+
+/**
+ *  @abstract The component's attributes.
+ */
+@property (nonatomic, readonly, strong) NSDictionary *attributes;
+
+/**
+ *  @abstract The component's events.
+ */
+@property (nonatomic, readonly, strong) NSArray *events;
+
+/**
+ *  @abstract The reference to
+ */
+@property (nonatomic, readonly, weak, nullable) WXSDKInstance *weexInstance;
+
+/**
+ * @abstract The component's subcomponents.
+ */
+@property (nonatomic, readonly, strong, nullable) NSArray<WXComponent *> *subcomponents;
+
+/**
+ * @abstract The component's supercomponent.
+ */
+@property (nonatomic, readonly, weak, nullable) WXComponent *supercomponent;
+
+///--------------------------------------
+/// @name Layout
+///--------------------------------------
+
+/**
+ * @abstract Return the calculated frame.
+ *
+ * @warning Subclasses must not override this.
+ */
+@property(nonatomic, readonly, assign) CGRect calculatedFrame;
+
+/**
+ * @abstract Return the calculated absolute position.
+ *
+ * @warning Subclasses must not override this.
+ */
+@property(nonatomic, assign) CGPoint absolutePosition;
+
+/**
+ * @abstract Return the css node used to layout.
+ *
+ * @warning Subclasses must not override this.
+ */
+@property(nonatomic, readonly, assign) css_node_t *cssNode;
+
+/**
+ * @abstract Invalidates the component's layout and marks it as needing an update.
+ *
+ * @discussion You can call this method to indicate that the layout of a component has changed and must be updated. Weex typically calls this method automatically when the layout-related styles change or when subcomponents are added or removed.
+ *
+ */
+- (void)setNeedsLayout;
+
+/**
+ * @abstract Returns a Boolean indicating whether the component has been marked as needing a layout update.
+ *
+ * @return YES if the component has been marked as requiring a layout update.
+ *
+ */
+- (BOOL)needsLayout;
+
+/**
+ * @abstract return a measure block for measure component's layout
+ *
+ * @param constrainedSize The maximum size the receiver should fit in.
+ *
+ * @return A block which will ask the component to measure and return the size that best fits for a constrained size.
+ *
+ * @discussion Subclasses can override this method to perform their own layout behaviour.  Weex will use the returned block to measure the component's layout, ignoring its own layout mechanism.
+ *
+ */
+- (nullable CGSize (^)(CGSize))measureBlock;
+
+/**
+ * @abstract Called on main thread when the component has just laid out.
+ */
+- (void)layoutDidFinish;
+
+
+///--------------------------------------
+/// @name View Management
+///--------------------------------------
+
+/**
+ * @abstract The view that the component manages.
+ *
+ * @discussion If you access this property and its value is currently nil, the component automatically calls the loadView method and returns the resulting view.
+ *
+ * @warning It must be on accessed on the main thread.Subclasses must not override this;
+ */
+@property(nonatomic, readonly, strong) UIView *view;
+
+/**
+ * @abstract The layer that the component manages.
+ *
+ * @discussion The layer property is also lazily initialized, similar to the view property.
+ *
+ * @warning It must be on accessed on the main thread. Subclasses must not override this;
+ */
+@property(nonatomic, readonly, strong) CALayer *layer;
+
+/**
+ * @abstract Creates the view that the component manages.
+ *
+ * @return View to be created
+ *
+ * @discussion This method loads or creates a view and assigns it to the view property. This is where subclasses should create their custom view hierarchy. Should never be called directly.The method is called on the main thread.
+ *
+ * @warning Your custom implementation of this method should not call super
+ */
+- (UIView *)loadView;
+
+/**
+ * @abstract Returns a Boolean value indicating whether the view is currently loaded.
+ */
+- (BOOL)isViewLoaded;
+
+/**
+ * @abstract Called before the load of component'��s view .
+ *
+ * @discussion This is before -loadView. The method is called on the main thread.
+ */
+- (void)viewWillLoad;
+
+/**
+ * @abstract Called after the component'��s view is loaded and set.
+ *
+ * @discussion This is after -loadView. This is the best time to perform additional initialization like adding gesture recognizers to the view.The method is called on the main thread.
+ */
+- (void)viewDidLoad;
+
+/**
+ * @abstract Called just before releasing the component'��s view.The method is called on the main thread.
+ */
+- (void)viewWillUnload;
+
+/**
+ * @abstract Called when the component'��s view is released.The method is called on the main thread.
+ */
+- (void)viewDidUnload;
+
+/**
+ * @abstract Inserts a subview at the specified index.
+ *
+ * @param subcomponent The subcomponent whose view will be inserted in the component's view.
+ * @param index        The index in the array of the subcomponents property at which to insert the view. subcomponent indices start at 0 and cannot be greater than the number of subcomponents.
+ *
+ * @discussion This will insert subcomponent's view to the view hierachy by default, it can be overrided to change the view hierachy. The method is called on the main thread.
+ */
+- (void)insertSubview:(WXComponent *)subcomponent atIndex:(NSInteger)index;
+
+/**
+ * @abstract Remove the component's view from its superview.
+ *
+ * @discussion The method is called on the main thread.
+ */
+- (void)removeFromSuperview;
+
+/**
+ * @abstract Moves the subview to a new super component in the scene. The node maintains its current position in scene coordinates.
+ *
+ * @param newSupercomponent An WXComponent object to move the component to
+ * @param index             The index in the array of the subcomponents property at which to insert the view. subcomponent indices start at 0 and cannot be greater than the number of subcomponents.
+ */
+- (void)moveToSuperview:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index;
+
+///--------------------------------------
+/// @name Events
+///--------------------------------------
+
+/**
+ * @abstract Fire an event to the component in Javascript.
+ *
+ * @param eventName The name of the event to fire
+ * @param params The parameters to fire with
+ **/
+- (void)fireEvent:(NSString *)eventName params:(nullable NSDictionary *)params;
+
+///--------------------------------------
+/// @name Updating
+///--------------------------------------
+
+/**
+ * @abstract Called when component's style are updated
+ *
+ * @param styles The updated style dictionary
+ * @discussion It can be overrided to handle specific style updating. The method is called on the main thread.
+ **/
+- (void)updateStyles:(NSDictionary *)styles;
+
+/**
+ * @abstract Called when component's attributes are updated
+ *
+ * @param attributes The updated attributes dictionary
+ * @discussion It can be overrided to handle specific attribute updating. The method is called on the main thread.
+ **/
+- (void)updateAttributes:(NSDictionary *)attributes;
+
+/**
+ * @abstract Called when adding an event to the component
+ *
+ * @param eventName The added event's name
+ * @discussion It can be overrided to handle specific event adding. The method is called on the main thread.
+ **/
+- (void)addEvent:(NSString *)eventName;
+
+/**
+ * @abstract Called when removing an event frome the component
+ *
+ * @param eventName The removed event's name
+ * @discussion It can be overrided to handle specific event removing. The method is called on the main thread.
+ **/
+- (void)removeEvent:(NSString *)evetName;
+
+///--------------------------------------
+/// @name Display
+///--------------------------------------
+
+typedef UIImage * _Nonnull(^WXDisplayBlock)(CGRect bounds, BOOL(^isCancelled)(void));
+typedef void(^WXDisplayCompeletionBlock)(CALayer *layer, BOOL finished);
+
+/**
+ * @abstract Marks the view as needing display. The method should be called on the main thread.
+ */
+- (void)setNeedsDisplay;
+
+/**
+ * @abstract Return a block to be called to draw layer.
+ *
+ * @discussion The block returned will be called on any thread.
+ *
+ */
+- (WXDisplayBlock)displayBlock;
+
+/**
+ * @abstract Return a block to be called while drawing is finished.
+ *
+ * @discussion The block returned will be called on main thread.
+ *
+ */
+- (WXDisplayCompeletionBlock)displayCompeletionBlock;
+
+@end
+
+@interface UIView (WXComponent)
+
+@property (nonatomic, weak) WXComponent *wx_component;
+
+@end
+
+@interface CALayer (WXComponent)
+
+@property (nonatomic, weak) WXComponent *wx_component;
+
+@end
+
+NS_ASSUME_NONNULL_END

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
new file mode 100644
index 0000000..6f900e9
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
@@ -0,0 +1,288 @@
+/**
+ * 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.h"
+#import "WXComponent_internal.h"
+#import "WXComponentManager.h"
+#import "WXSDKManager.h"
+#import "WXSDKInstance.h"
+#import "WXSDKInstance_private.h"
+#import "WXDefine.h"
+#import "WXLog.h"
+#import "WXWeakObjectWrapper.h"
+#import "WXUtility.h"
+#import "WXConvert.h"
+#import "WXAssert.h"
+#import "WXThreadSafeMutableDictionary.h"
+#import "WXThreadSafeMutableArray.h"
+
+#pragma clang diagnostic ignored "-Wincomplete-implementation"
+
+@interface WXComponent () <UIGestureRecognizerDelegate>
+
+@end
+
+@implementation WXComponent
+{
+@private
+    NSString *_ref;
+    WXThreadSafeMutableDictionary *_styles;
+    WXThreadSafeMutableDictionary *_attributes;
+    WXThreadSafeMutableArray *_events;
+    
+    WXThreadSafeMutableArray *_subcomponents;
+    __weak WXComponent *_supercomponent;
+    __weak id<WXScrollerProtocol> _ancestorScroller;
+    __weak WXSDKInstance *_weexInstance;
+}
+
+#pragma mark Life Cycle
+
+- (instancetype)initWithRef:(NSString *)ref
+                       type:(NSString *)type
+                     styles:(NSDictionary *)styles
+                 attributes:(NSDictionary *)attributes
+                     events:(NSArray *)events
+               weexInstance:(WXSDKInstance *)weexInstance
+{
+    if (self = [super init]) {
+        _ref = ref;
+        _type = type;
+        _weexInstance = weexInstance;
+        _styles = styles ? [WXThreadSafeMutableDictionary dictionaryWithDictionary:styles] : [WXThreadSafeMutableDictionary dictionary];
+        _attributes = attributes ? [WXThreadSafeMutableDictionary dictionaryWithDictionary:attributes] : [WXThreadSafeMutableDictionary dictionary];
+        _events = events ? [WXThreadSafeMutableArray arrayWithArray:events] : [WXThreadSafeMutableArray array];
+        
+        _subcomponents = [WXThreadSafeMutableArray array];
+        
+        _isNeedJoinLayoutSystem = YES;
+        _isLayoutDirty = YES;
+        
+        _async = NO;
+        
+        //TODO set indicator style 
+        if ([type isEqualToString:@"indicator"]) {
+            _styles[@"position"] = @"absolute";
+            if (!_styles[@"left"] && !_styles[@"right"]) {
+                _styles[@"left"] = @0.0f;
+            }
+            if (!_styles[@"top"] && !_styles[@"bottom"]) {
+                _styles[@"top"] = @0.0f;
+            }
+        }
+        
+        [self _setupNavBarWithStyles:_styles attributes:_attributes];
+        [self _initCSSNodeWithStyles:_styles];
+        [self _initViewPropertyWithStyles:_styles];
+        [self _handleBorders:styles isUpdating:NO];
+    }
+    
+    return self;
+}
+
+- (void)dealloc
+{
+    free_css_node(_cssNode);
+}
+
+- (NSDictionary *)styles
+{
+    return _styles;
+}
+
+- (NSDictionary *)attributes
+{
+    return _attributes;
+}
+
+- (WXSDKInstance *)weexInstance
+{
+    return _weexInstance;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"<%@ ref=%@> %@", _type, _ref, _view];
+}
+
+#pragma mark Component Hierarchy 
+
+- (NSArray<WXComponent *> *)subcomponents
+{
+    return _subcomponents;
+}
+
+- (WXComponent *)supercomponent
+{
+    return _supercomponent;
+}
+
+- (void)_insertSubcomponent:(WXComponent *)subcomponent atIndex:(NSInteger)index
+{
+    WXAssert(subcomponent, @"The subcomponent to insert to %@ at index %d must not be nil", self, index);
+    
+    subcomponent->_supercomponent = self;
+    
+    [_subcomponents insertObject:subcomponent atIndex:index];
+    
+    if (subcomponent->_positionType == WXPositionTypeFixed) {
+        [self.weexInstance.componentManager addFixedComponent:subcomponent];
+        subcomponent->_isNeedJoinLayoutSystem = NO;
+    }
+    
+    [self _recomputeCSSNodeChildren];
+    [self setNeedsLayout];
+}
+
+- (void)_removeFromSupercomponent
+{
+    [self.supercomponent->_subcomponents removeObject:self];
+    [self.supercomponent _recomputeCSSNodeChildren];
+    [self.supercomponent setNeedsLayout];
+    
+    if (_positionType == WXPositionTypeFixed) {
+        [self.weexInstance.componentManager removeFixedComponent:self];
+        self->_isNeedJoinLayoutSystem = YES;
+    }
+}
+
+- (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index
+{
+    [self _removeFromSupercomponent];
+    [newSupercomponent _insertSubcomponent:self atIndex:index];
+}
+
+- (id<WXScrollerProtocol>)ancestorScroller
+{
+    if(!_ancestorScroller){
+        WXComponent *supercomponent = self.supercomponent;
+        while (supercomponent) {
+            if([supercomponent conformsToProtocol:@protocol(WXScrollerProtocol)]){
+                _ancestorScroller = (id<WXScrollerProtocol>)supercomponent;
+                break;
+            }
+            supercomponent = supercomponent.supercomponent;
+        }
+    }
+    
+    return _ancestorScroller;
+}
+
+#pragma mark Updating
+
+- (void)_updateStylesOnComponentThread:(NSDictionary *)styles
+{
+    [_styles addEntriesFromDictionary:styles];
+    [self _updateCSSNodeStyles:styles];
+}
+
+- (void)_updateAttributesOnComponentThread:(NSDictionary *)attributes
+{
+    [_attributes addEntriesFromDictionary:attributes];
+}
+
+- (void)_addEventOnComponentThread:(NSString *)eventName
+{
+    [_events addObject:eventName];
+}
+
+- (void)_removeEventOnComponentThread:(NSString *)eventName
+{
+    [_events removeObject:eventName];
+}
+
+- (void)_updateStylesOnMainThread:(NSDictionary *)styles
+{
+    WXAssertMainThread();
+    
+    [self _updateViewStyles:styles];
+    [self _handleBorders:styles isUpdating:YES];
+    
+    [self updateStyles:styles];
+}
+
+- (void)_updateAttributesOnMainThread:(NSDictionary *)attributes
+{
+    WXAssertMainThread();
+    
+    [[_attributes mutableCopy] addEntriesFromDictionary:attributes];
+    
+    [self _updateNavBarAttributes:attributes];
+    
+    [self updateAttributes:attributes];
+}
+
+- (void)updateStyles:(NSDictionary *)styles
+{
+    WXAssertMainThread();
+}
+
+- (void)updateAttributes:(NSDictionary *)attributes
+{
+    WXAssertMainThread();
+}
+
+#pragma mark Layout
+
+/**
+ *  @see WXComponents+Layout.m
+ */
+
+#pragma mark View Management
+
+/**
+ *  @see WXComponents+ViewManagement.m
+ */
+
+#pragma mark Events
+
+/**
+ *  @see WXComponents+Events.m
+ */
+
+#pragma mark Display
+
+/**
+ *  @see WXComponents+Display.m
+ */
+
+@end
+
+
+@implementation UIView (WXComponent)
+
+- (WXComponent *)wx_component
+{
+    WXWeakObjectWrapper *weakWrapper = objc_getAssociatedObject(self, @selector(wx_component));
+    return [weakWrapper weakObject];
+}
+
+- (void)setWx_component:(WXComponent *)wx_component
+{
+    id weakWrapper = [[WXWeakObjectWrapper alloc] initWithWeakObject:wx_component];
+    objc_setAssociatedObject(self, @selector(wx_component), weakWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+@end
+
+@implementation CALayer (WXComponents_new)
+
+- (WXComponent *)wx_component
+{
+    WXWeakObjectWrapper *weakWrapper = objc_getAssociatedObject(self, @selector(wx_component));
+    return [weakWrapper weakObject];
+}
+
+- (void)setWx_component:(WXComponent *)wx_component
+{
+    id weakWrapper = [[WXWeakObjectWrapper alloc] initWithWeakObject:wx_component];
+    objc_setAssociatedObject(self, @selector(wx_component), weakWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+@end
+

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
new file mode 100644
index 0000000..20988bb
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
@@ -0,0 +1,200 @@
+/**
+ * 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>
+#import "WXComponent.h"
+
+extern NSString *const bundleUrlOptionKey;
+
+@interface WXSDKInstance : NSObject
+
+/**
+ * The viewControler which the weex bundle is rendered in.
+ **/
+@property (nonatomic, weak) UIViewController *viewController;
+
+/**
+ * The rootView which the weex bundle is rendered at.
+ **/
+@property (nonatomic, strong) UIView *rootView;
+
+/**
+ * The scriptURL of weex bundle.
+ **/
+@property (nonatomic, strong) NSURL *scriptURL;
+
+/**
+ * The parent instance.
+ **/
+@property (nonatomic, weak) WXSDKInstance *parentInstance;
+
+/**
+ * The node reference of parent instance.
+ **/
+@property (nonatomic, weak) NSString *parentNodeRef;
+
+/**
+ * The unique id to indentify current weex instance.
+ **/
+@property (nonatomic, strong) NSString *instanceId;
+
+/**
+ * The state of current instance.
+ **/
+typedef NS_ENUM(NSInteger, WXState) {//state.code
+    WeexInstanceAppear = 100,
+    WeexInstanceDisappear,
+    WeexInstanceForeground,
+    WeexInstanceBackground,
+    WeexInstanceMemoryWarning,
+    WeexInstanceDestroy
+};
+
+@property (nonatomic, assign) WXState state;
+
+/**
+ *  The callback triggered when the instance finishes creating the body.
+ *
+ *  @param view The rootView.
+ **/
+@property (nonatomic, copy) void (^onCreate)(UIView *);
+
+/**
+ *  The callback triggered when the instance finishes refreshing weex view.
+ *
+ *  @param view The rootView.
+ **/
+@property (nonatomic, copy) void (^refreshFinish)(UIView *);
+
+/**
+ *  The callback triggered when the instance finishes rendering.
+ *
+ *  @param view The rootView.
+ **/
+@property (nonatomic, copy) void (^renderFinish)(UIView *);
+
+/**
+ *  The callback triggered when the instance finishes updating.
+ *
+ *  @param view The rootView.
+ **/
+@property (nonatomic, copy) void (^updateFinish)(UIView *);
+
+
+typedef NS_ENUM(NSInteger, WXErrorType) {//error.domain
+    TemplateErrorType = 1,
+};
+typedef NS_ENUM(NSInteger, WXErrorCode) {//error.code
+    PlatformErrorCode = 1000,
+    OSVersionErrorCode,
+    AppVersionErrorCode,
+    WeexSDKVersionErrorCode,
+    DeviceModelErrorCode,
+    FrameworkVersionErrorCode,
+};
+
+/**
+ *  The callback triggered when the instance fails to render.
+ *
+ *  @param error The error code .
+ **/
+@property (nonatomic, copy) void (^onFailed)(NSError *error);
+
+/**
+ *  The callback triggered when the instacne executes scrolling .
+ *
+ *  @param contentOffset The point at which the origin of the content view is offset from the origin of the scroll view
+ **/
+@property (nonatomic, copy) void (^onScroll)(CGPoint contentOffset);
+
+/**
+ * the callback to be run repeatedly while the instance is rendering.
+ *
+ * @param renderRect The view's frame that is just rendered.
+ **/
+@property (nonatomic, copy) void (^onRenderProgress)(CGRect renderRect);
+
+/**
+ *  the frame of current instance.
+ **/
+@property (nonatomic, assign) CGRect frame;
+
+/**
+ *  the info stored by user.
+ */
+@property (nonatomic, strong) NSDictionary *userInfo;
+
+/**
+ * Renders weex view with bundle url.
+ *
+ * @param url The url of bundle rendered to a weex view.
+ **/
+- (void)renderWithURL:(NSURL *)url;
+
+/**
+ * Renders weex view with bundle url and some others.
+ *
+ * @param url The url of bundle rendered to a weex view.
+ *
+ * @param options The params passed by user, sometimes you should pass the value of "bundleUrl".
+ *
+ * @param data The data the bundle needs when rendered.
+ **/
+- (void)renderWithURL:(NSURL *)url options:(NSDictionary *)options data:(id)data;
+
+/**
+ * Renders weex view with source string of bundle and some others.
+ *
+ * @param url The source string of bundle rendered to a weex view.
+ *
+ * @param options The params passed by user, sometimes you should pass the value of "bundleUrl".
+ *
+ * @param data The data the bundle needs when rendered.
+ **/
+- (void)renderView:(NSString *)source options:(NSDictionary *)options data:(id)data;
+
+/**
+ * Refreshes current instance with data.
+ *
+ * @param data The data the bundle needs when rendered.
+ **/
+- (void)refreshInstance:(id)data;
+
+/**
+ * Destroys current instance.
+ **/
+- (void)destroyInstance;
+
+/**
+ * get module instance by class
+ */
+- (id)moduleForClass:(Class)moduleClass;
+
+/**
+ * get Componet instance by ref
+ */
+- (WXComponent *) componentForRef:(NSString *)ref;
+
+/**
+ * application performance statistics
+ */
+@property (nonatomic, strong) NSString *bizType;
+@property (nonatomic, strong) NSString *pageName;
+@property (nonatomic, strong) NSDictionary *properties;
+@property (nonatomic, weak) id pageObject;
+@property (nonatomic, strong) NSDate *renderStartDate;
+@property (nonatomic) NSTimeInterval networkTime;
+@property (nonatomic) NSTimeInterval communicateTime;
+extern NSTimeInterval JSLibInitTime;
+@property (nonatomic) NSTimeInterval screenRenderTime;
+
+- (void)finishPerformance;
+
+- (void)reloadData:(id)data  DEPRECATED_MSG_ATTRIBUTE("Use refreshInstance: method instead.");
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
new file mode 100644
index 0000000..5903940
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
@@ -0,0 +1,314 @@
+/**
+ * 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 "WXSDKInstance.h"
+#import "WXSDKInstance_private.h"
+#import "WXSDKManager.h"
+#import "WXAppMonitorProtocol.h"
+#import "WXNetworkProtocol.h"
+#import "WXModuleFactory.h"
+#import "WXHandlerFactory.h"
+#import "WXDebugTool.h"
+#import "WXUtility.h"
+#import "WXLog.h"
+#import "WXView.h"
+
+NSString *const bundleUrlOptionKey = @"bundleUrl";
+
+NSTimeInterval JSLibInitTime = 0;
+
+@implementation WXSDKInstance
+{
+    id<WXNetworkProtocol> _networkHandler;
+    
+    WXComponentManager *_componentManager;
+}
+
+- (void) dealloc
+{
+    [self removeObservers];
+}
+
+- (instancetype)init
+{
+    self = [super init];
+    if(self){
+        NSInteger instanceId = 0;
+        @synchronized(self){
+            static NSInteger __instance = 0;
+            instanceId = __instance % (1024*1024);
+            __instance++;
+        }
+        _instanceId = [NSString stringWithFormat:@"%ld", (long)instanceId];
+
+        [WXSDKManager storeInstance:self forID:_instanceId];
+        _frame = CGRectMake(NAN, NAN, NAN, NAN);
+        
+        _bizType = @"";
+        _pageName = @"";
+        _screenRenderTime = 0;
+        
+        _frame = CGRectMake(NAN, NAN, NAN, NAN);
+        _moduleInstances = [NSMutableDictionary new];
+        _styleConfigs = [NSMutableDictionary new];
+        _attrConfigs = [NSMutableDictionary new];
+       
+        [self addObservers];
+    }
+    return self;
+}
+
+#pragma mark Public Mehtods
+
+- (void)renderWithURL:(NSURL *)url
+{
+    [self renderWithURL:url options:nil data:nil];
+}
+
+- (void)renderWithURL:(NSURL *)url options:(NSDictionary *)options data:(id)data
+{
+    WXLogInfo(@"Render URL: %@", url);
+    if (!url) {
+        WXLogError(@"Url must be passed if you use renderWithURL");
+        return;
+    }
+    
+    _scriptURL = url;
+    NSMutableDictionary *newOptions = [options mutableCopy];
+    newOptions[bundleUrlOptionKey] = url.absoluteString;
+    
+    if (!self.pageName || [self.pageName isEqualToString:@""]) {
+        self.pageName = url.absoluteString ? : @"";
+    }
+    
+    __weak typeof(self) weakSelf = self;
+    if ([url isFileURL]) {
+        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+            NSString *path = [url path];
+            NSData *scriptData = [[NSFileManager defaultManager] contentsAtPath:path];
+            NSString *script = [[NSString alloc] initWithData:scriptData encoding:NSUTF8StringEncoding];
+            if (!script) {
+                NSString *errorDesc = [NSString stringWithFormat:@"File read error at url: %@", url];
+                WXLogError(@"%@", errorDesc);
+                if (weakSelf.onFailed) {
+                    weakSelf.onFailed([NSError errorWithDomain:WX_ERROR_DOMAIN code:0 userInfo:@{NSLocalizedDescriptionKey: errorDesc}]);
+                }
+                return;
+            }
+            [weakSelf renderView:script options:newOptions data:data];
+        });
+    } else {
+        NSDate *networkStart = [NSDate date];
+        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
+        [request setValue:[WXUtility userAgent] forHTTPHeaderField:@"User-Agent"];
+        
+        id<WXNetworkProtocol> networkHandler = [self networkHandler];
+        
+        __block NSURLResponse *urlResponse;
+        [networkHandler sendRequest:request
+                   withSendingData:^(int64_t bytesSent, int64_t totalBytes) {}
+                      withResponse:^(NSURLResponse *response) {
+                          urlResponse = response;
+                      }
+                   withReceiveData:^(NSData *data) {}
+                   withCompeletion:^(NSData *totalData, NSError *error) {
+            //TODO 304
+            if (!error && [urlResponse isKindOfClass:[NSHTTPURLResponse class]] && ((NSHTTPURLResponse *)urlResponse).statusCode != 200) {
+                error = [NSError errorWithDomain:WX_ERROR_DOMAIN
+                                                     code:((NSHTTPURLResponse *)urlResponse).statusCode
+                                                 userInfo:@{@"message":@"status code error."}];
+            }
+            
+           if (error) {
+               WXLogError(@"Connection to %@ occurs an error:%@", request.URL, error);
+               if (weakSelf.onFailed) {
+                   weakSelf.onFailed(error);
+               }
+               return ;
+           }
+                   
+            NSString *script = [[NSString alloc] initWithData:totalData encoding:NSUTF8StringEncoding];
+            weakSelf.networkTime = -[networkStart timeIntervalSinceNow];
+            [weakSelf renderView:script options:newOptions data:data];
+        }];
+    }
+}
+
+- (void)renderView:(NSString *)source options:(NSDictionary *)options data:(id)data
+{
+    WXLogVerbose(@"Render view: %@, data:%@", self, [WXUtility JSONString:data]);
+    
+    if (!self.instanceId) {
+        WXLogError(@"Fail to find instance\uff01");
+        return;
+    }
+    
+    _renderStartDate = [NSDate new];
+    
+    NSMutableDictionary *dictionary = [options mutableCopy];
+    if ([WXLog logLevel] >= WXLogLevelVerbose) {
+        dictionary[@"debug"] = @(YES);
+    }
+    
+    if ([WXDebugTool getReplacedBundleJS]) {
+        source = [WXDebugTool getReplacedBundleJS];
+    }
+    
+    //TODO WXRootView
+    self.rootView = [[WXView alloc] initWithFrame:self.frame];
+    if(self.onCreate) {
+        self.onCreate(self.rootView);
+    }
+    
+    [[WXSDKManager bridgeMgr] createInstance:self.instanceId template:source options:dictionary data:data];
+}
+
+- (void)setFrame:(CGRect)frame
+{
+    _frame = frame;
+//    [self.componentManager changeRootFrame];
+}
+
+- (void)reloadData:(id)data
+{
+    [self refreshInstance:data];
+}
+
+- (void)refreshInstance:(id)data
+{
+    WXLogVerbose(@"refresh instance: %@, data:%@", self, [WXUtility JSONString:data]);
+    
+    if (!self.instanceId) {
+        WXLogError(@"Fail to find instance\uff01");
+        return;
+    }
+    
+    [[WXSDKManager bridgeMgr] refreshInstance:self.instanceId data:data];
+}
+
+- (void)destroyInstance
+{
+    if (!self.instanceId) {
+        WXLogError(@"Fail to find instance\uff01");
+        return;
+    }
+    
+    [[WXSDKManager bridgeMgr] destroyInstance:self.instanceId];
+    
+    __weak typeof(self) weakSelf = self;
+    WXPerformBlockOnComponentThread(^{
+        [self.componentManager unload];
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [WXSDKManager removeInstanceforID:weakSelf.instanceId];
+        });
+    });
+}
+
+- (void)updateState:(WXState)state
+{
+    if (!self.instanceId) {
+        WXLogError(@"Fail to find instance\uff01");
+        return;
+    }
+    
+    NSMutableDictionary *data = [NSMutableDictionary dictionary];
+    [data setObject:[NSNumber numberWithLong:state] forKey:@"state"];
+    [[WXSDKManager bridgeMgr] updateState:self.instanceId data:data];
+}
+
+- (id)moduleForClass:(Class)moduleClass
+{
+    if (!moduleClass)
+        return nil;
+    
+    id<WXModuleProtocol> moduleInstance = self.moduleInstances[NSStringFromClass(moduleClass)];
+    if (!moduleInstance) {
+        moduleInstance = [[moduleClass alloc] init];
+        if ([moduleInstance respondsToSelector:@selector(setWeexInstance:)])
+            [moduleInstance setWeexInstance:self];
+        self.moduleInstances[NSStringFromClass(moduleClass)] = moduleInstance;
+    }
+    
+    return moduleInstance;
+}
+
+- (WXComponent *)componentForRef:(NSString *)ref
+{
+    return [self.componentManager componentForRef:ref];
+}
+
+- (void)finishPerformance
+{
+    NSTimeInterval totalTime = 0;
+    if (_renderStartDate) {
+        totalTime = [[NSDate new] timeIntervalSinceDate:_renderStartDate];
+    }
+    else {
+        NSAssert(NO, @"");
+    }
+    
+    NSDictionary* dict = @{BIZTYPE:self.bizType,
+                           PAGENAME:self.pageName,
+                           WXSDKVERSION:WX_SDK_VERSION,
+                           NETWORKTIME:@(_networkTime * 1000),
+                           COMMUNICATETIME:[NSNumber numberWithDouble:_communicateTime * 1000],
+                           JSLIBINITTIME:[NSNumber numberWithDouble:JSLibInitTime * 1000],
+                           SCREENRENDERTIME:[NSNumber numberWithDouble:(_screenRenderTime > 0 ? _screenRenderTime : totalTime) * 1000],
+                           TOTALTIME:[NSNumber numberWithDouble:totalTime * 1000]
+                           };
+    WXLogInfo(@"Performance: %@", dict);
+    
+    id<WXAppMonitorProtocol> appMonitor = [WXHandlerFactory handlerForProtocol:@protocol(WXAppMonitorProtocol)];
+    if (appMonitor && [appMonitor respondsToSelector:@selector(commitAppMonitorArgs:)]){
+        [appMonitor commitAppMonitorArgs:dict];
+    }
+}
+
+#pragma mark Private Methods
+
+- (void)addObservers
+{
+    [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
+}
+
+- (void)removeObservers
+{
+    [self removeObserver:self forKeyPath:@"state"];
+}
+
+- (WXComponentManager *)componentManager
+{
+    if (!_componentManager) {
+        _componentManager = [[WXComponentManager alloc] initWithWeexInstance:self];
+    }
+    
+    return _componentManager;
+}
+
+- (id<WXNetworkProtocol>)networkHandler
+{
+    if (!_networkHandler) {
+        _networkHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXNetworkProtocol)];
+    }
+    
+    return _networkHandler;
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+    if ([keyPath isEqualToString:@"state"]) {
+        WXState state = [change[@"new"] longValue];
+        [self updateState:state];
+        
+        if (state == WeexInstanceDestroy) {
+            [self destroyInstance];
+        }
+    }
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h
new file mode 100644
index 0000000..3ec3059
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h
@@ -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 <Foundation/Foundation.h>
+#import "WXSDKInstance.h"
+#import "WXComponentManager.h"
+
+@interface WXSDKInstance ()
+
+@property (nonatomic, strong) NSMutableDictionary *moduleInstances;
+@property (nonatomic, strong) NSMutableDictionary *naviBarStyles;
+@property (nonatomic, strong) NSMutableDictionary *styleConfigs;
+@property (nonatomic, strong) NSMutableDictionary *attrConfigs;
+
+@property (nonatomic, readonly, strong) WXComponentManager *componentManager;
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h
new file mode 100644
index 0000000..592bcb4
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h
@@ -0,0 +1,14 @@
+/**
+ * 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 "WXModuleProtocol.h"
+
+@interface WXAnimationModule : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
new file mode 100644
index 0000000..bd88ba7
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
@@ -0,0 +1,75 @@
+/**
+ * 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 "WXAnimationModule.h"
+#import "WXSDKInstance_private.h"
+#import "WXConvert.h"
+#import "WXTransform.h"
+
+@implementation WXAnimationModule
+
+@synthesize weexInstance;
+
+WX_EXPORT_METHOD(@selector(transition:args:callback:))
+
+- (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXModuleCallback)callback
+{
+    WXComponent *targetComponent = [self.weexInstance componentForRef:nodeRef];
+    if (!targetComponent) {
+        callback([NSString stringWithFormat:@"No component find for ref:%@", nodeRef]);
+        return;
+    }
+    
+    CALayer *layer = targetComponent.layer;
+    UIView *view = targetComponent.view;
+    
+    NSDictionary *styles = args[@"styles"];
+    
+    NSTimeInterval duration = [args[@"duration"] doubleValue] / 1000;
+    NSTimeInterval delay = [args[@"delay"] doubleValue] / 1000;
+//    CAMediaTimingFunction *timingFunction = [WXConvert CAMediaTimingFunction:args[@"timingFunction"]];
+    UIViewAnimationOptions timingFunction = [WXConvert UIViewAnimationTimingFunction:args[@"timingFunction"]];
+    
+    // Rotate 360 not work , have not found any solution
+    // http://stackoverflow.com/questions/9844925/uiview-infinite-360-degree-rotation-animation
+    [UIView animateWithDuration:duration delay:delay options:UIViewAnimationOptionAllowUserInteraction | timingFunction animations:^{
+        for (NSString *property in styles) {
+            if ([property isEqualToString:@"transform"]) {
+                NSString *transformOrigin = styles[@"transformOrigin"];
+                layer.transform = [[WXTransform new] getTransform:styles[property] withView:view withOrigin:transformOrigin];
+            } else if ([property isEqualToString:@"backgroundColor"]) {
+                layer.backgroundColor = [WXConvert CGColor:styles[property]];
+            } else if ([property isEqualToString:@"opacity"]) {
+                layer.opacity = [styles[property] floatValue];
+            }
+        }
+    } completion:^(BOOL finished) {
+        if (callback) {
+            callback(finished ? @"SUCCESS" : @"FAIL");
+        }
+    }];
+    
+//
+//    CAAnimationGroup *group = [CAAnimationGroup animation];
+//    group.fillMode = kCAFillModeForwards;
+//    group.removedOnCompletion = NO;
+//    group.timingFunction = timingFunction;
+//    group.animations = animations;
+//    group.delegate = self;
+//    group.beginTime = CACurrentMediaTime() + delay;
+//    group.duration = duration;
+//
+//    _callback = [callback copy];
+//    [layer addAnimation:group forKey:nil];
+}
+
+//- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
+//{
+//}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXDomModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXDomModule.h b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.h
new file mode 100644
index 0000000..be9367f
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.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 "WXModuleProtocol.h"
+
+@interface WXDomModule : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
new file mode 100644
index 0000000..49bdb39
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
@@ -0,0 +1,148 @@
+/**
+ * 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 "WXDomModule.h"
+#import "WXDefine.h"
+#import "WXSDKManager.h"
+#import "WXComponentManager.h"
+#import "WXSDKInstance_private.h"
+#import "WXLog.h"
+#import "WXModuleProtocol.h"
+
+@interface WXDomModule ()
+
+@end
+
+@implementation WXDomModule
+
+@synthesize weexInstance;
+
+WX_EXPORT_METHOD(@selector(createBody:))
+WX_EXPORT_METHOD(@selector(addElement:element:atIndex:))
+WX_EXPORT_METHOD(@selector(removeElement:))
+WX_EXPORT_METHOD(@selector(moveElement:parentRef:index:))
+WX_EXPORT_METHOD(@selector(addEvent:event:))
+WX_EXPORT_METHOD(@selector(removeElement:))
+WX_EXPORT_METHOD(@selector(createFinish))
+WX_EXPORT_METHOD(@selector(updateFinish))
+WX_EXPORT_METHOD(@selector(refreshFinish))
+WX_EXPORT_METHOD(@selector(scrollToElement:options:))
+WX_EXPORT_METHOD(@selector(updateStyle:styles:))
+WX_EXPORT_METHOD(@selector(updateAttrs:attrs:))
+
+- (void)performBlockOnComponentMananger:(void(^)(WXComponentManager *))block
+{
+    if (!block) {
+        return;
+    }
+    __weak typeof(self) weakSelf = self;
+    
+    WXPerformBlockOnComponentThread(^{
+        WXComponentManager *mananger = weakSelf.weexInstance.componentManager;
+        [mananger startComponentTasks];
+        block(mananger);
+    });
+}
+
+- (NSThread *)targetExecuteThread
+{
+    return [WXComponentManager componentThread];
+}
+
+- (void)createBody:(NSDictionary *)body
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager createRoot:body];
+    }];
+}
+
+- (void)addElement:(NSString *)parentRef element:(NSDictionary *)element atIndex:(NSInteger)index
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager addComponent:element toSupercomponent:parentRef atIndex:index appendingInTree:NO];
+    }];
+}
+
+- (void)removeElement:(NSString *)ref
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager removeComponent:ref];
+    }];
+}
+
+- (void)moveElement:(NSString *)elemRef parentRef:(NSString *)parentRef index:(NSInteger)index
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager moveComponent:elemRef toSuper:parentRef atIndex:index];
+    }];
+}
+
+- (void)addEvent:(NSString *)elemRef event:(NSString *)event
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager addEvent:event toComponent:elemRef];
+    }];
+}
+
+- (void)removeEvent:(NSString *)elemRef event:(NSString *)event
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager removeEvent:event fromComponent:elemRef];
+    }];
+}
+
+- (void)createFinish
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager createFinish];
+    }];
+}
+
+- (void)updateFinish
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager updateFinish];
+    }];
+}
+
+- (void)refreshFinish
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager refreshFinish];
+    }];
+}
+
+- (void)scrollToElement:(NSString *)elemRef options:(NSDictionary *)dict
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager scrollToComponent:elemRef options:dict];
+    }];
+}
+
+-(void)updateStyle:(NSString *)elemRef styles:(NSDictionary *)styles
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager updateStyles:styles forComponent:elemRef];
+    }];
+}
+
+- (void)updateAttrs:(NSString *)elemRef attrs:(NSDictionary *)attrs
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager updateAttributes:attrs forComponent:elemRef];
+    }];
+}
+
+- (void)destoryInstance
+{
+    [self performBlockOnComponentMananger:^(WXComponentManager *manager) {
+        [manager unload];
+    }];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.h b/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.h
new file mode 100644
index 0000000..a7da464
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.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 "WXModuleProtocol.h"
+
+@interface WXInstanceWrap : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.m b/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.m
new file mode 100644
index 0000000..ce6d077
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXInstanceWrap.m
@@ -0,0 +1,44 @@
+/**
+ * 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 "WXInstanceWrap.h"
+#import "WXEmbedComponent.h"
+
+@implementation WXInstanceWrap
+
+@synthesize weexInstance;
+
+WX_EXPORT_METHOD(@selector(error:code:info:))
+WX_EXPORT_METHOD(@selector(refresh))
+
+- (void)error:(NSInteger)type code:(NSInteger)code info:(NSString *)info
+{
+    NSString *domain = [NSString stringWithFormat:@"%ld", (long)type];
+    NSDictionary *userInfo = @{ NSLocalizedDescriptionKey:info };
+    NSError *error = [NSError errorWithDomain:domain code:code userInfo:userInfo];
+    if (weexInstance.onFailed)
+        weexInstance.onFailed(error);
+}
+
+- (void)refresh
+{
+    if (self.weexInstance.parentInstance) {
+        WXSDKInstance *instance = self.weexInstance.parentInstance;
+        NSString *nodeRef = self.weexInstance.parentNodeRef;
+        WXEmbedComponent *embedComponent= (WXEmbedComponent *)[instance componentForRef:nodeRef];
+        [embedComponent refreshWeex];
+    }
+    else {
+        UIViewController *controller = self.weexInstance.viewController;
+        if ([controller respondsToSelector:@selector(refreshWeex)]) {
+            [controller performSelector:@selector(refreshWeex) withObject:nil];
+        }
+    }
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.h b/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.h
new file mode 100644
index 0000000..8305bdc
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.h
@@ -0,0 +1,14 @@
+/**
+ * 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 "WXModuleProtocol.h"
+
+@interface WXModalUIModule : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m b/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m
new file mode 100644
index 0000000..21e9261
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m
@@ -0,0 +1,308 @@
+/**
+ * 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 "WXModalUIModule.h"
+#import <objc/runtime.h>
+#import "WXUtility.h"
+#import "WXAssert.h"
+
+static NSString *WXModalCallbackKey;
+
+typedef enum : NSUInteger {
+    WXModalTypeToast = 1,
+    WXModalTypeAlert,
+    WXModalTypeConfirm,
+    WXModalTypePrompt
+} WXModalType;
+
+@interface WXToastInfo : NSObject
+
+@property (nonatomic, strong) UIView *toastView;
+@property (nonatomic, weak) UIView *superView;
+@property (nonatomic, assign) double duration;
+
+@end
+
+@implementation WXToastInfo
+
+@end
+
+@interface WXToastManager : NSObject
+
+@property (strong, nonatomic) NSMutableArray<WXToastInfo *> *toastQueue;
+@property (strong, nonatomic) UIView *toastingView;
+
++ (WXToastManager *)sharedManager;
+
+@end
+
+@implementation WXToastManager
+
++ (WXToastManager *)sharedManager{
+    static WXToastManager * shareInstance;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        shareInstance = [[WXToastManager alloc] init];
+        shareInstance.toastQueue = [NSMutableArray new];
+    });
+    return shareInstance;
+}
+
+@end
+
+@interface WXModalUIModule () <UIAlertViewDelegate>
+
+@end
+
+@implementation WXModalUIModule
+
+@synthesize weexInstance;
+
+WX_EXPORT_METHOD(@selector(toast:))
+WX_EXPORT_METHOD(@selector(alert:callback:))
+WX_EXPORT_METHOD(@selector(confirm:callback:))
+WX_EXPORT_METHOD(@selector(prompt:callback:))
+
+#pragma mark - Toast
+
+static const double WXToastDefaultDuration = 3.0;
+static const CGFloat WXToastDefaultFontSize = 16.0;
+static const CGFloat WXToastDefaultWidth = 230.0;
+static const CGFloat WXToastDefaultHeight = 30.0;
+static const CGFloat WXToastDefaultPadding = 30.0;
+
+- (void)toast:(NSDictionary *)param
+{
+    NSString *message = param[@"message"];
+    if (!message) return;
+    
+    double duration = [param[@"duration"] doubleValue];
+    if (duration <= 0) {
+        duration = WXToastDefaultDuration;
+    }
+    
+    WXPerformBlockOnMainThread(^{
+        [self toast:message duration:duration];
+    });
+}
+
+- (void)toast:(NSString *)message duration:(double)duration
+{
+    WXAssertMainThread();
+    UIView *superView =  [[[UIApplication sharedApplication] windows] objectAtIndex:0];
+    if (!superView) {
+        superView =  self.weexInstance.rootView;
+    }
+    UIView *toastView = [self toastViewForMessage:message superView:superView];
+    WXToastInfo *info = [WXToastInfo new];
+    info.toastView = toastView;
+    info.superView = superView;
+    info.duration = duration;
+    [[WXToastManager sharedManager].toastQueue addObject:info];
+    
+    if (![WXToastManager sharedManager].toastingView) {
+        [self showToast:toastView superView:superView duration:duration];
+    }
+}
+
+- (UIView *)toastViewForMessage:(NSString *)message superView:(UIView *)superView
+{
+    CGFloat padding = WXToastDefaultPadding;
+    UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(padding/2, padding/2, WXToastDefaultWidth, WXToastDefaultHeight)];
+    messageLabel.numberOfLines =  0;
+    messageLabel.textAlignment = NSTextAlignmentCenter;
+    messageLabel.text = message;
+    messageLabel.font = [UIFont boldSystemFontOfSize:WXToastDefaultFontSize];
+    messageLabel.lineBreakMode = NSLineBreakByTruncatingTail;
+    messageLabel.textColor = [UIColor whiteColor];
+    messageLabel.backgroundColor = [UIColor clearColor];
+    [messageLabel sizeToFit];
+
+    UIView *toastView = [[UIView alloc] initWithFrame:
+                         CGRectMake(
+                                    (superView.frame.size.width-messageLabel.frame.size.width-padding)/2,
+                                    (superView.frame.size.height-messageLabel.frame.size.height-padding)/2,
+                                    messageLabel.frame.size.width+padding,
+                                    messageLabel.frame.size.height+padding
+                                    )];
+    
+    CGPoint point = CGPointZero;
+    UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
+    
+    // adjust to screen orientation
+    UIInterfaceOrientation orientation = (UIInterfaceOrientation)[[UIApplication sharedApplication] statusBarOrientation];
+    switch (orientation) {
+        case UIDeviceOrientationPortrait: {
+            point = CGPointMake(window.frame.size.width/2, window.frame.size.height/2);
+            break;
+        }
+        case UIDeviceOrientationPortraitUpsideDown: {
+            toastView.transform = CGAffineTransformMakeRotation(M_PI);
+            float width = window.frame.size.width;
+            float height = window.frame.size.height;
+            point = CGPointMake(width/2, height/2);
+            break;
+        }
+        case UIDeviceOrientationLandscapeLeft: {
+            toastView.transform = CGAffineTransformMakeRotation(M_PI/2); //rotation in radians
+            point = CGPointMake(window.frame.size.width/2, window.frame.size.height/2);
+            break;
+        }
+        case UIDeviceOrientationLandscapeRight: {
+            toastView.transform = CGAffineTransformMakeRotation(-M_PI/2);
+            point = CGPointMake(window.frame.size.width/2, window.frame.size.height/2);
+            break;
+        }
+        default:
+            break;
+    }
+    
+    toastView.center = point;
+    toastView.frame = CGRectIntegral(toastView.frame);
+    
+    [toastView addSubview:messageLabel];
+    toastView.layer.cornerRadius = 7;
+    toastView.backgroundColor=[UIColor colorWithWhite:0 alpha:0.7];
+    
+    return toastView;
+}
+
+- (void)showToast:(UIView *)toastView superView:(UIView *)superView duration:(double)duration
+{
+    if (!toastView || !superView) {
+        return;
+    }
+    
+    [WXToastManager sharedManager].toastingView = toastView;
+    [superView addSubview:toastView];
+    
+    [UIView animateWithDuration:0.2 delay:duration options:UIViewAnimationOptionCurveEaseInOut animations:^{
+        toastView.transform = CGAffineTransformConcat(toastView.transform, CGAffineTransformMakeScale(0.8, 0.8)) ;
+    } completion:^(BOOL finished) {
+        [UIView animateWithDuration:0.2 delay:0.2 options:UIViewAnimationOptionCurveEaseInOut animations:^{
+            toastView.alpha = 0;
+        } completion:^(BOOL finished){
+            [toastView removeFromSuperview];
+            [WXToastManager sharedManager].toastingView = nil;
+            
+            NSMutableArray *queue = [WXToastManager sharedManager].toastQueue;
+            if (queue.count > 0) {
+                [queue removeObjectAtIndex:0];
+                if (queue.count > 0) {
+                    WXToastInfo *info = [queue firstObject];
+                    [self showToast:info.toastView superView:info.superView duration:info.duration];
+                }
+            }
+        }];
+    }];
+}
+
+#pragma mark - Alert
+
+- (void)alert:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    NSString *message = param[@"message"];
+    NSString *okTitle = param[@"okTitle"];
+    
+    if ([WXUtility isBlankString:okTitle]) {
+        okTitle = @"OK";
+    }
+
+    [self alert:message okTitle:nil cancelTitle:okTitle defaultText:nil type:WXModalTypeAlert callback:callback];
+}
+
+#pragma mark - Confirm
+
+- (void)confirm:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    NSString *message = param[@"message"];
+    NSString *okTitle = param[@"okTitle"];
+    NSString *cancelTitle = param[@"cancelTitle"];
+    
+    if ([WXUtility isBlankString:okTitle]) {
+        okTitle = @"OK";
+    }
+    if ([WXUtility isBlankString:cancelTitle]) {
+        cancelTitle = @"Cancel";
+    }
+
+    [self alert:message okTitle:okTitle cancelTitle:cancelTitle defaultText:nil type:WXModalTypeConfirm callback:callback];
+}
+
+#pragma mark - Prompt
+
+- (void)prompt:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    NSString *message = param[@"message"];
+    NSString *defaultValue = param[@"default"];
+    NSString *okTitle = param[@"okTitle"];
+    NSString *cancelTitle = param[@"cancelTitle"];
+    
+    if ([WXUtility isBlankString:okTitle]) {
+        okTitle = @"OK";
+    }
+    if ([WXUtility isBlankString:cancelTitle]) {
+        cancelTitle = @"Cancel";
+    }
+    
+    [self alert:message okTitle:okTitle cancelTitle:cancelTitle defaultText:defaultValue type:WXModalTypePrompt callback:callback];
+}
+
+
+#pragma mark - Private
+
+- (void)alert:(NSString *)message okTitle:(NSString *)okTitle cancelTitle:(NSString *)cancelTitle defaultText:(NSString *)defaultText type:(WXModalType)type callback:(WXModuleCallback)callback
+{
+    if (!message) {
+        callback(@"Error: message should be passed.");
+        return;
+    }
+    
+    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"" message:message delegate:self cancelButtonTitle:cancelTitle otherButtonTitles:okTitle, nil];
+    alertView.tag = type;
+    if (type == WXModalTypePrompt) {
+        alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
+        UITextField *textField = [alertView textFieldAtIndex:0];
+        textField.placeholder = defaultText;
+    }
+    objc_setAssociatedObject(alertView, &WXModalCallbackKey, [callback copy], OBJC_ASSOCIATION_COPY_NONATOMIC);
+    
+    WXPerformBlockOnMainThread(^{
+        [alertView show];
+    });
+}
+
+- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+    WXModuleCallback callback = objc_getAssociatedObject(alertView, &WXModalCallbackKey);
+    if (!callback) return;
+    
+    NSString *result = @"";
+    switch (alertView.tag) {
+        case WXModalTypeAlert: {
+            result = @"";
+            break;
+        }
+        case WXModalTypeConfirm: {
+            NSString *clickTitle = [alertView buttonTitleAtIndex:buttonIndex];
+            result = clickTitle;
+            break;
+        }
+        case WXModalTypePrompt: {
+            NSString *clickTitle = [alertView buttonTitleAtIndex:buttonIndex];
+            NSString *text= [[alertView textFieldAtIndex:0] text] ?: @"";
+            result = [WXUtility JSONString:@{ @"result": clickTitle, @"data": text }];
+        }
+        default:
+            break;
+    }
+    
+    callback(result);
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.h b/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.h
new file mode 100644
index 0000000..3327e6a
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.h
@@ -0,0 +1,14 @@
+/**
+ * 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 <WeexSDK/WXModuleProtocol.h>
+
+@interface WXNavigatorModule : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.m b/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.m
new file mode 100644
index 0000000..37dbae3
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXNavigatorModule.m
@@ -0,0 +1,156 @@
+/**
+ * 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 "WXNavigatorModule.h"
+#import "WXSDKManager.h"
+#import "WXUtility.h"
+#import "WXBaseViewController.h"
+#import "WXNavigationProtocol.h"
+#import "WXHandlerFactory.h"
+#import "WXConvert.h"
+
+@implementation WXNavigatorModule
+
+@synthesize weexInstance;
+
+WX_EXPORT_METHOD(@selector(push:callback:))
+WX_EXPORT_METHOD(@selector(pop:callback:))
+WX_EXPORT_METHOD(@selector(close:callback:))
+WX_EXPORT_METHOD(@selector(setNavBarBackgroundColor:callback:))
+WX_EXPORT_METHOD(@selector(setNavBarLeftItem:callback:))
+WX_EXPORT_METHOD(@selector(clearNavBarLeftItem:callback:))
+WX_EXPORT_METHOD(@selector(setNavBarRightItem:callback:))
+WX_EXPORT_METHOD(@selector(clearNavBarRightItem:callback:))
+WX_EXPORT_METHOD(@selector(setNavBarMoreItem:callback:))
+WX_EXPORT_METHOD(@selector(clearNavBarMoreItem:callback:))
+WX_EXPORT_METHOD(@selector(setNavBarTitle:callback:))
+WX_EXPORT_METHOD(@selector(clearNavBarTitle:callback:))
+
+- (id<WXNavigationProtocol>)navigator
+{
+    id<WXNavigationProtocol> navigator = [WXHandlerFactory handlerForProtocol:@protocol(WXNavigationProtocol)];
+    return navigator;
+}
+
+#pragma mark Weex Application Interface
+
+- (void)push:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    id<WXNavigationProtocol> navigator = [self navigator];
+    UIViewController *container = self.weexInstance.viewController;
+    [navigator pushViewControllerWithParam:param completion:^(NSString *code, NSDictionary *responseData) {
+        if (callback && code) {
+            callback(code);
+        }
+    } withContainer:container];
+}
+
+- (void)pop:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    id<WXNavigationProtocol> navigator = [self navigator];
+    UIViewController *container = self.weexInstance.viewController;
+    [navigator popViewControllerWithParam:param completion:^(NSString *code, NSDictionary *responseData) {
+        if (callback && code) {
+            callback(code);
+        }
+    } withContainer:container];
+}
+
+- (void)close:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    id<WXNavigationProtocol> navigator = [self navigator];
+    UIViewController *container = self.weexInstance.viewController;
+    [navigator popToRootViewControllerWithParam:param completion:^(NSString *code, NSDictionary *responseData) {
+        if (callback && code) {
+            callback(code);
+        }
+    } withContainer:container];
+}
+
+#pragma mark Navigation Setup
+
+- (void)setNavBarBackgroundColor:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    NSString *backgroundColor = param[@"backgroundColor"];
+    if (!backgroundColor) {
+        callback(MSG_PARAM_ERR);
+    }
+    
+    id<WXNavigationProtocol> navigator = [self navigator];
+    UIViewController *container = self.weexInstance.viewController;
+    [navigator setNavigationBackgroundColor:[WXConvert UIColor:backgroundColor] withContainer:container];
+    callback(MSG_SUCCESS);
+}
+
+- (void)setNavBarRightItem:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self setNavigationItemWithParam:param position:WXNavigationItemPositionRight withCallback:callback];
+}
+
+- (void)clearNavBarRightItem:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self clearNavigationItemWithParam:param position:WXNavigationItemPositionRight withCallback:callback];
+}
+
+- (void)setNavBarLeftItem:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self setNavigationItemWithParam:param position:WXNavigationItemPositionLeft withCallback:callback];
+}
+
+- (void)clearNavBarLeftItem:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self clearNavigationItemWithParam:param position:WXNavigationItemPositionLeft withCallback:callback];
+}
+
+- (void)setNavBarMoreItem:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self setNavigationItemWithParam:param position:WXNavigationItemPositionMore withCallback:callback];
+}
+
+- (void)clearNavBarMoreItem:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self clearNavigationItemWithParam:param position:WXNavigationItemPositionMore withCallback:callback];
+}
+
+- (void)setNavBarTitle:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self setNavigationItemWithParam:param position:WXNavigationItemPositionCenter withCallback:callback];
+}
+
+- (void)clearNavBarTitle:(NSDictionary *)param callback:(WXModuleCallback)callback
+{
+    [self clearNavigationItemWithParam:param position:WXNavigationItemPositionCenter withCallback:callback];
+}
+
+- (void)setNavigationItemWithParam:(NSDictionary *)param position:(WXNavigationItemPosition)position withCallback:(WXModuleCallback)callback
+{
+    id<WXNavigationProtocol> navigator = [self navigator];
+    UIViewController *container = self.weexInstance.viewController;
+    
+    NSMutableDictionary *mutableParam = [param mutableCopy];
+    [mutableParam setObject:self.weexInstance.instanceId forKey:@"instanceId"];
+    
+    [navigator setNavigationItemWithParam:mutableParam position:position completion:^(NSString *code, NSDictionary *responseData) {
+        if (callback && code) {
+            callback(code);
+        }
+    } withContainer:container];
+}
+
+- (void)clearNavigationItemWithParam:(NSDictionary *)param position:(WXNavigationItemPosition)position withCallback:(WXModuleCallback)callback
+{
+    id<WXNavigationProtocol> navigator = [self navigator];
+    UIViewController *container = self.weexInstance.viewController;
+    [navigator clearNavigationItemWithParam:param position:position completion:^(NSString *code, NSDictionary *responseData) {
+        if (callback && code) {
+            callback(code);
+        }
+    } withContainer:container];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.h b/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.h
new file mode 100644
index 0000000..fe79e81
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.h
@@ -0,0 +1,14 @@
+/**
+ * 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>
+#import <WeexSDK/WXModuleProtocol.h>
+
+@interface WXStorageModule : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m b/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m
new file mode 100644
index 0000000..a458c87
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXStorageModule.m
@@ -0,0 +1,202 @@
+/**
+ * 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 "WXStorageModule.h"
+#import <WeexSDK/WXSDKManager.h>
+#import <WeexSDK/WXUtility.h>
+
+#define defaultKey  @"default"
+#define LocalStoreFile @"store.plist"
+
+@implementation WXStorageModule
+{
+    NSString *_plist;
+    BOOL _setupFinished;
+}
+
+@synthesize weexInstance;
+
+
+WX_EXPORT_METHOD(@selector(mutiSet:callback:))
+WX_EXPORT_METHOD(@selector(mutiGet:callback:))
+WX_EXPORT_METHOD(@selector(mutiRemove:callback:))
+WX_EXPORT_METHOD(@selector(clear:))
+
+static dispatch_queue_t WXStorageQueue()
+{
+    static dispatch_queue_t queue;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        queue = dispatch_queue_create("com.taobao.weex.storageQueue", NULL);
+    });
+    return queue;
+}
+
+- (id)init
+{
+    self= [super init];
+    if (self) {
+        [self setup];
+    }
+    return self;
+}
+
+- (void)setup
+{
+    _setupFinished = NO;
+    _plist = [WXDocumentPath stringByAppendingString: LocalStoreFile];
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    if (![fileManager fileExistsAtPath:_plist]) {
+        BOOL ret = [fileManager createFileAtPath:_plist contents:nil attributes:nil];
+        if (ret) {
+            _setupFinished = YES;
+        }
+    }
+    else {
+        _setupFinished = YES;
+    }
+}
+
+- (void)mutiSet:(id)data callback:(NSString *)callback {
+    
+    if (!_setupFinished) {
+        return;
+    }
+    
+    dispatch_async(WXStorageQueue(), ^{
+        NSData *storeData = [NSData dataWithContentsOfFile:_plist];
+        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:storeData];
+        NSMutableDictionary *inputDict = [unarchiver decodeObjectForKey:defaultKey] ;
+        [unarchiver finishDecoding];
+        
+        if (!inputDict) {
+            inputDict = [NSMutableDictionary new];
+        }
+    
+        NSEnumerator *enumerator = [data keyEnumerator];
+        NSString *key;
+        while ((key = [enumerator nextObject])) {
+            id object = [data objectForKey:key];
+            [inputDict setObject:object forKey:key];
+            [WXGlobalCache setObject:object forKey:key];
+        }
+        
+        NSMutableData *ouputData = [[NSMutableData alloc] init];
+        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:ouputData];
+        [archiver encodeObject:inputDict forKey:defaultKey];
+        [archiver finishEncoding];
+        
+        [ouputData writeToFile:_plist atomically:YES];
+        
+        NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                           @"success", @"result",
+                                            nil];
+        NSString *params = WXEncodeJson(dict);
+        [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:callback params:params];
+    });
+}
+
+-(void)mutiGet:(id)data callback:(NSString *)callback
+{
+    if (!_setupFinished || ![data isKindOfClass:[NSArray class]]) {
+        return;
+    }
+    
+    dispatch_async(WXStorageQueue(), ^{
+        
+        NSMutableArray *keys = [NSMutableArray arrayWithArray:data];
+        NSMutableDictionary *retValue = [NSMutableDictionary new];
+        
+        for (id key in data) {
+            id object = [WXGlobalCache objectForKey:key];
+            if (object) {
+                [retValue setObject:object forKey:key];
+                [keys removeObject:key];
+            }
+        }
+        
+        if ([keys count] > 0) {
+            NSData *storeData = [NSData dataWithContentsOfFile:_plist];
+            NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:storeData];
+            NSDictionary *inputDict = [unarchiver decodeObjectForKey:defaultKey];
+            [unarchiver finishDecoding];
+            
+            for (id key in keys) {
+                id object = [inputDict objectForKey:key];
+                if (object) {
+                    [retValue setObject:object forKey:key];
+                    [WXGlobalCache setObject:object forKey:key];
+                }
+                else {
+                    [retValue setObject:@"" forKey:key];
+                }
+            }
+        }
+        
+        NSString *params = WXEncodeJson(retValue);
+        [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:callback params:params];
+    });
+}
+
+- (void)mutiRemove:(id)data callback:(NSString *)callback
+{
+    if (!_setupFinished || ![data isKindOfClass:[NSArray class]]) {
+        return;
+    }
+    
+    dispatch_async(WXStorageQueue(), ^{
+        NSArray *keys = (NSArray *)data;
+        NSData *storeData = [NSData dataWithContentsOfFile:_plist];
+        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:storeData];
+        NSMutableDictionary *inputDict = [unarchiver decodeObjectForKey:defaultKey];
+        [unarchiver finishDecoding];
+        
+        for (NSString *key in keys) {
+            [inputDict removeObjectForKey:key];
+            [WXGlobalCache removeObjectForKey:key];
+        }
+        
+        NSMutableData *ouputData = [[NSMutableData alloc] init];
+        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:ouputData];
+        [archiver encodeObject:inputDict forKey:defaultKey];
+        [archiver finishEncoding];
+        
+        [ouputData writeToFile:_plist atomically:YES];
+        
+        NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                     @"success", @"result",
+                                     nil];
+        NSString *params = WXEncodeJson(dict);
+        [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:callback params:params];
+    });
+}
+
+- (void)clear:(NSString *)callback
+{
+    if (!_setupFinished) {
+        return;
+    }
+    
+    dispatch_async(WXStorageQueue(), ^{
+        NSData *storeData = [NSData dataWithContentsOfFile:_plist];
+        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:storeData];
+        NSMutableDictionary *inputDict = [unarchiver decodeObjectForKey:defaultKey];
+        [unarchiver finishDecoding];
+        
+        [inputDict removeAllObjects];
+        [WXGlobalCache removeAllObjects];
+        
+        NSMutableData *ouputData = [[NSMutableData alloc] init];
+        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:ouputData];
+        [archiver encodeObject:inputDict forKey:defaultKey];
+        [archiver finishEncoding];
+    });
+}
+
+@end
+

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.h b/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.h
new file mode 100644
index 0000000..f561d2d
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.h
@@ -0,0 +1,14 @@
+/**
+ * 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 "WXModuleProtocol.h"
+
+@interface WXStreamModule : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m b/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m
new file mode 100644
index 0000000..94f0ec9
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m
@@ -0,0 +1,152 @@
+/**
+ * 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 "WXStreamModule.h"
+#import "WXSDKManager.h"
+#import "WXUtility.h"
+#import "WXHandlerFactory.h"
+#import "WXNetworkProtocol.h"
+
+@implementation WXStreamModule
+
+@synthesize weexInstance;
+
+WX_EXPORT_METHOD(@selector(sendHttp:callback:))
+WX_EXPORT_METHOD(@selector(fetch:progressCallback:callback:))
+
+- (void)sendHttp:(NSDictionary*)param callback:(WXModuleCallback)callback
+{
+    NSString* method = [param objectForKey:@"method"];
+    NSString* urlStr = [param objectForKey:@"url"];
+    NSDictionary* header = [param objectForKey:@"header"];
+    NSString* body = [param objectForKey:@"body"];
+    
+    NSURL *url = [NSURL URLWithString:urlStr];
+    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
+    [request setHTTPMethod:method];
+    [request setTimeoutInterval:60.0];
+    for (NSString *key in header) {
+        NSString *value = [header objectForKey:key];
+        [request setValue:value forHTTPHeaderField:key];
+    }
+    [request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
+    [request setValue:[WXUtility userAgent] forHTTPHeaderField:@"User-Agent"];
+    
+    id<WXNetworkProtocol> networkHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXNetworkProtocol)];
+    
+    [networkHandler sendRequest:request
+                withSendingData:^(int64_t bytesSent, int64_t totalBytes) {
+                 } withResponse:^(NSURLResponse *response) {
+              } withReceiveData:^(NSData *data) {
+              } withCompeletion:^(NSData *totalData, NSError *error) {
+                    NSString *responseData = nil;
+                    if (!error) {
+                        responseData = [[NSString alloc] initWithData:totalData encoding:NSUTF8StringEncoding];
+                    }
+                    //else ok
+                    callback(responseData);
+              }];
+}
+
+- (void)fetch:(NSDictionary *)options progressCallback:(NSString *)progressCallback callback:(WXModuleCallback)callback {
+    __block NSInteger received = 0;
+    __block NSHTTPURLResponse *httpResponse = nil;
+    __block NSMutableDictionary * callbackRsp =[[NSMutableDictionary alloc] init];
+    __block NSString *statusText = @"ERR_CONNECT_FAILED";
+    
+    NSString *method = [options objectForKey:@"method"];
+    if ([WXUtility isBlankString:method]) {
+        method = @"GET";
+    }
+    NSString *urlStr = [options objectForKey:@"url"];
+    if (!options || [WXUtility isBlankString:urlStr]) {
+        [callbackRsp setObject:@(-1) forKey:@"status"];
+        [callbackRsp setObject:@false forKey:@"ok"];
+        
+        callback([WXUtility JSONString:callbackRsp]);
+        
+        return;
+    }
+    NSDictionary *headers = [options objectForKey:@"headers"];
+    NSString *body = [options objectForKey:@"body"];
+    
+    NSURL *url = [NSURL URLWithString:urlStr];
+    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
+    [request setHTTPMethod:method];
+    [request setTimeoutInterval:60.0];
+    for (NSString *header in headers) {
+        NSString *value = [headers objectForKey:header];
+        [request setValue:value forHTTPHeaderField:header];
+    }
+    [request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
+    [request setValue:[WXUtility userAgent] forHTTPHeaderField:@"User-Agent"];
+   
+    [callbackRsp setObject:@{ @"OPENED": @1 } forKey:@"readyState"];
+    
+    [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:progressCallback params:[WXUtility JSONString:callbackRsp] keepAlive:true];
+    
+    id<WXNetworkProtocol> networkHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXNetworkProtocol)];
+    [networkHandler sendRequest:request
+                withSendingData:^(int64_t bytesSent, int64_t totalBytes) {
+                } withResponse:^(NSURLResponse *response) {
+                    httpResponse = (NSHTTPURLResponse*)response;
+                    
+                    [callbackRsp setObject:@{ @"HEADERS_RECEIVED" : @2  } forKey:@"readyState"];
+                    [callbackRsp setObject:[NSNumber numberWithInteger:httpResponse.statusCode] forKey:@"status"];
+                    [callbackRsp setObject:httpResponse.allHeaderFields forKey:@"headers"];
+                    if (httpResponse.statusCode == 200) {
+                        statusText = @"OK";
+                    }else {
+                        statusText = [NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode].capitalizedString;
+                    }
+                    [callbackRsp setObject:statusText forKey:@"statusText"];
+                    [callbackRsp setObject:[NSNumber numberWithInteger:received] forKey:@"length"];
+                    
+                    [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:progressCallback params:[WXUtility JSONString:callbackRsp] keepAlive:true];
+                    
+                } withReceiveData:^(NSData *data) {
+                    [callbackRsp setObject:@{ @"LOADING" : @3  } forKey:@"readyState"];
+                    received += [data length];
+                    [callbackRsp setObject:[NSNumber numberWithInteger:received] forKey:@"length"];
+                    
+                    [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:progressCallback params:[WXUtility JSONString:callbackRsp] keepAlive:true];
+                    
+                } withCompeletion:^(NSData *totalData, NSError *error) {
+                    
+                    [callbackRsp removeObjectForKey:@"readyState"];
+                    [callbackRsp removeObjectForKey:@"length"];
+                    [callbackRsp removeObjectForKey:@"keepalive"];
+                    [callbackRsp setObject:httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299?@true : @false forKey:@"ok"];
+                    if (error) {
+                        //error
+                        [callbackRsp setObject:@(-1) forKey:@"status"];
+                        [callbackRsp setObject:[NSString stringWithFormat:@"%@(%ld)",[error localizedDescription], (long)[error code]] forKey:@"data"];
+                        
+                        switch ([error code]) {
+                            case -1000:
+                            case -1002:
+                            case -1003:
+                                statusText = @"ERR_INVALID_REQUEST";
+                                break;
+                            default:
+                                break;
+                        }
+                        [callbackRsp setObject:statusText forKey:@"statusText"];
+                        
+                    }else {
+                        // no error
+                        NSString *responseData = nil;
+                        responseData = [[NSString alloc] initWithData:totalData encoding:NSUTF8StringEncoding];
+                        [callbackRsp setObject:responseData forKey:@"data"];
+                    }
+                    
+                    callback([WXUtility JSONString:callbackRsp]);
+                }];
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.h b/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.h
new file mode 100644
index 0000000..5b83ac8
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.h
@@ -0,0 +1,14 @@
+/**
+ * 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 "WXModuleProtocol.h"
+
+@interface WXTimerModule : NSObject <WXModuleProtocol>
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.m b/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.m
new file mode 100644
index 0000000..4785880
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXTimerModule.m
@@ -0,0 +1,75 @@
+/**
+ * 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 "WXTimerModule.h"
+#import "WXSDKManager.h"
+
+@interface WXTimerModule ()
+
+@property (nonatomic, strong) NSMutableDictionary *timerMap;
+
+@end
+
+@implementation WXTimerModule
+
+@synthesize weexInstance;
+
+WX_EXPORT_METHOD(@selector(setTimeout:time:))
+WX_EXPORT_METHOD(@selector(clearTimeout:))
+
+// When timer fires notify JS
+- (void)timerRespones:(NSInteger) callbackId {
+    if (self.weexInstance) {
+        [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:[@(callbackId) stringValue] params:nil];
+    }
+    [self clearTimeout:callbackId];
+}
+
+// Add timer
+- (void)setTimeout:(NSInteger)callbackId time:(NSInteger)time {
+    SEL method = @selector(timerRespones:);
+    NSMethodSignature *signature = [self methodSignatureForSelector:method];
+    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
+    [invocation setTarget: self];
+    [invocation setSelector:method];
+    [invocation setArgument:&callbackId atIndex:2];
+
+    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:time/1000.0 invocation:invocation repeats:NO];
+    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
+
+    if (_timerMap == nil) {
+        _timerMap = [[NSMutableDictionary alloc] init];
+    }
+
+    [_timerMap setValue:timer forKey:[@(callbackId) stringValue]];
+}
+
+// Remove Timer
+- (void)clearTimeout:(NSInteger)callbackId  {
+    NSString *key = [@(callbackId) stringValue];
+    NSTimer *timer = [_timerMap valueForKey:key];
+    if (timer) {
+        [timer invalidate];
+        timer = nil;
+        [_timerMap removeObjectForKey:key];
+    }
+}
+
+- (void)dealloc {
+    if (_timerMap) {
+        for (NSString *key in _timerMap) {
+            NSTimer *timer = [_timerMap valueForKey:key];
+            [timer invalidate];
+            timer = nil;
+        }
+        [_timerMap removeAllObjects];
+        _timerMap = nil;
+    }
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/185fe55c/ios/sdk/WeexSDK/Sources/Module/WXWebViewModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXWebViewModule.h b/ios/sdk/WeexSDK/Sources/Module/WXWebViewModule.h
new file mode 100644
index 0000000..56d50bb
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXWebViewModule.h
@@ -0,0 +1,15 @@
+/**
+ * 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 "WXModuleProtocol.h"
+#import "WXDomModule.h"
+
+@interface WXWebViewModule : WXDomModule <WXModuleProtocol>
+
+@end