mirror of
https://github.com/zhigang1992/HybridWebView.git
synced 2026-04-28 20:15:18 +08:00
init commit
This commit is contained in:
@@ -14,6 +14,11 @@
|
||||
180DDFA41AD4C6B100EFAC49 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 180DDFA31AD4C6B100EFAC49 /* Images.xcassets */; };
|
||||
180DDFA71AD4C6B100EFAC49 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 180DDFA51AD4C6B100EFAC49 /* LaunchScreen.xib */; };
|
||||
180DDFB31AD4C6B100EFAC49 /* ObjCAddJSInterfaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 180DDFB21AD4C6B100EFAC49 /* ObjCAddJSInterfaceTests.m */; };
|
||||
180DDFBE1AD4C6E100EFAC49 /* UIWebView+AddJavaScriptInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 180DDFBD1AD4C6E100EFAC49 /* UIWebView+AddJavaScriptInterface.m */; };
|
||||
180DDFC21AD4C7D500EFAC49 /* YQWebViewProxyDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 180DDFC11AD4C7D500EFAC49 /* YQWebViewProxyDelegate.m */; };
|
||||
180DDFC71AD5328000EFAC49 /* YQAddJSInterface.js in Resources */ = {isa = PBXBuildFile; fileRef = 180DDFC61AD5328000EFAC49 /* YQAddJSInterface.js */; };
|
||||
18C876E11AD617D80080F561 /* test.html in Resources */ = {isa = PBXBuildFile; fileRef = 18C876E01AD617D80080F561 /* test.html */; };
|
||||
18DF31A31AD7A4340000872F /* UINavigationItem+Addition.m in Sources */ = {isa = PBXBuildFile; fileRef = 18DF31A21AD7A4340000872F /* UINavigationItem+Addition.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -40,6 +45,14 @@
|
||||
180DDFAC1AD4C6B100EFAC49 /* ObjCAddJSInterfaceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ObjCAddJSInterfaceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
180DDFB11AD4C6B100EFAC49 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
180DDFB21AD4C6B100EFAC49 /* ObjCAddJSInterfaceTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ObjCAddJSInterfaceTests.m; sourceTree = "<group>"; };
|
||||
180DDFBC1AD4C6E100EFAC49 /* UIWebView+AddJavaScriptInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIWebView+AddJavaScriptInterface.h"; path = "ObjCAddJSInterface/UIWebView+AddJavaScriptInterface.h"; sourceTree = "<group>"; };
|
||||
180DDFBD1AD4C6E100EFAC49 /* UIWebView+AddJavaScriptInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIWebView+AddJavaScriptInterface.m"; path = "ObjCAddJSInterface/UIWebView+AddJavaScriptInterface.m"; sourceTree = "<group>"; };
|
||||
180DDFC01AD4C7D500EFAC49 /* YQWebViewProxyDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YQWebViewProxyDelegate.h; path = ObjCAddJSInterface/YQWebViewProxyDelegate.h; sourceTree = "<group>"; };
|
||||
180DDFC11AD4C7D500EFAC49 /* YQWebViewProxyDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YQWebViewProxyDelegate.m; path = ObjCAddJSInterface/YQWebViewProxyDelegate.m; sourceTree = "<group>"; };
|
||||
180DDFC61AD5328000EFAC49 /* YQAddJSInterface.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = YQAddJSInterface.js; path = ObjCAddJSInterface/YQAddJSInterface.js; sourceTree = "<group>"; };
|
||||
18C876E01AD617D80080F561 /* test.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = test.html; sourceTree = "<group>"; };
|
||||
18DF31A11AD7A4340000872F /* UINavigationItem+Addition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationItem+Addition.h"; sourceTree = "<group>"; };
|
||||
18DF31A21AD7A4340000872F /* UINavigationItem+Addition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationItem+Addition.m"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -81,14 +94,18 @@
|
||||
180DDF951AD4C6B100EFAC49 /* ObjCAddJSInterface */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18C876E01AD617D80080F561 /* test.html */,
|
||||
180DDF9A1AD4C6B100EFAC49 /* AppDelegate.h */,
|
||||
180DDF9B1AD4C6B100EFAC49 /* AppDelegate.m */,
|
||||
180DDF9D1AD4C6B100EFAC49 /* ViewController.h */,
|
||||
180DDF9E1AD4C6B100EFAC49 /* ViewController.m */,
|
||||
18DF31A11AD7A4340000872F /* UINavigationItem+Addition.h */,
|
||||
18DF31A21AD7A4340000872F /* UINavigationItem+Addition.m */,
|
||||
180DDFA01AD4C6B100EFAC49 /* Main.storyboard */,
|
||||
180DDFA31AD4C6B100EFAC49 /* Images.xcassets */,
|
||||
180DDFA51AD4C6B100EFAC49 /* LaunchScreen.xib */,
|
||||
180DDF961AD4C6B100EFAC49 /* Supporting Files */,
|
||||
180DDFBF1AD4C6EC00EFAC49 /* AddJavaScriptInterface */,
|
||||
);
|
||||
path = ObjCAddJSInterface;
|
||||
sourceTree = "<group>";
|
||||
@@ -119,6 +136,18 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
180DDFBF1AD4C6EC00EFAC49 /* AddJavaScriptInterface */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
180DDFC61AD5328000EFAC49 /* YQAddJSInterface.js */,
|
||||
180DDFBC1AD4C6E100EFAC49 /* UIWebView+AddJavaScriptInterface.h */,
|
||||
180DDFBD1AD4C6E100EFAC49 /* UIWebView+AddJavaScriptInterface.m */,
|
||||
180DDFC01AD4C7D500EFAC49 /* YQWebViewProxyDelegate.h */,
|
||||
180DDFC11AD4C7D500EFAC49 /* YQWebViewProxyDelegate.m */,
|
||||
);
|
||||
name = AddJavaScriptInterface;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -202,6 +231,8 @@
|
||||
180DDFA21AD4C6B100EFAC49 /* Main.storyboard in Resources */,
|
||||
180DDFA71AD4C6B100EFAC49 /* LaunchScreen.xib in Resources */,
|
||||
180DDFA41AD4C6B100EFAC49 /* Images.xcassets in Resources */,
|
||||
18C876E11AD617D80080F561 /* test.html in Resources */,
|
||||
180DDFC71AD5328000EFAC49 /* YQAddJSInterface.js in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -219,9 +250,12 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
180DDFBE1AD4C6E100EFAC49 /* UIWebView+AddJavaScriptInterface.m in Sources */,
|
||||
180DDF9F1AD4C6B100EFAC49 /* ViewController.m in Sources */,
|
||||
18DF31A31AD7A4340000872F /* UINavigationItem+Addition.m in Sources */,
|
||||
180DDF9C1AD4C6B100EFAC49 /* AppDelegate.m in Sources */,
|
||||
180DDF991AD4C6B100EFAC49 /* main.m in Sources */,
|
||||
180DDFC21AD4C7D500EFAC49 /* YQWebViewProxyDelegate.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -412,6 +446,7 @@
|
||||
180DDFB81AD4C6B100EFAC49 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
180DDFB91AD4C6B100EFAC49 /* Build configuration list for PBXNativeTarget "ObjCAddJSInterfaceTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
@@ -420,6 +455,7 @@
|
||||
180DDFBB1AD4C6B100EFAC49 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
scope = "0"
|
||||
stopOnStyle = "0">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
@@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "180DDF921AD4C6B100EFAC49"
|
||||
BuildableName = "ObjCAddJSInterface.app"
|
||||
BlueprintName = "ObjCAddJSInterface"
|
||||
ReferencedContainer = "container:ObjCAddJSInterface.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "180DDFAB1AD4C6B100EFAC49"
|
||||
BuildableName = "ObjCAddJSInterfaceTests.xctest"
|
||||
BlueprintName = "ObjCAddJSInterfaceTests"
|
||||
ReferencedContainer = "container:ObjCAddJSInterface.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "180DDFAB1AD4C6B100EFAC49"
|
||||
BuildableName = "ObjCAddJSInterfaceTests.xctest"
|
||||
BlueprintName = "ObjCAddJSInterfaceTests"
|
||||
ReferencedContainer = "container:ObjCAddJSInterface.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "180DDF921AD4C6B100EFAC49"
|
||||
BuildableName = "ObjCAddJSInterface.app"
|
||||
BlueprintName = "ObjCAddJSInterface"
|
||||
ReferencedContainer = "container:ObjCAddJSInterface.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "180DDF921AD4C6B100EFAC49"
|
||||
BuildableName = "ObjCAddJSInterface.app"
|
||||
BlueprintName = "ObjCAddJSInterface"
|
||||
ReferencedContainer = "container:ObjCAddJSInterface.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "180DDF921AD4C6B100EFAC49"
|
||||
BuildableName = "ObjCAddJSInterface.app"
|
||||
BlueprintName = "ObjCAddJSInterface"
|
||||
ReferencedContainer = "container:ObjCAddJSInterface.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>ObjCAddJSInterface.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>180DDF921AD4C6B100EFAC49</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>180DDFAB1AD4C6B100EFAC49</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,13 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1514" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="h0w-9k-4QK">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="dbi-yY-dng">
|
||||
<objects>
|
||||
<navigationController id="h0w-9k-4QK" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="FGF-cv-cCe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="vXZ-lx-hvc" kind="relationship" relationship="rootViewController" id="eQa-CW-nhQ"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Mfq-pQ-RrR" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-683" y="120"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="ufC-wZ-h7g">
|
||||
<objects>
|
||||
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
|
||||
<viewController id="vXZ-lx-hvc" customClass="ViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
|
||||
@@ -15,8 +31,18 @@
|
||||
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<webView contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QFd-st-RZF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</webView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="bg2-OV-Z86"/>
|
||||
<connections>
|
||||
<outlet property="webView" destination="QFd-st-RZF" id="Iy0-3n-HFp"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// UIWebView+AddJavaScriptInterface.h
|
||||
// ObjCAddJSInterface
|
||||
//
|
||||
// Created by wangyaqing on 15/4/8.
|
||||
// Copyright (c) 2015年 billwang1990.github.io. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class YQWebViewProxyDelegate;
|
||||
|
||||
@interface UIWebView (AddJavaScriptInterface)
|
||||
|
||||
- (void) addJavascriptInterfaces:(NSObject*) interface WithName:(NSString*) name;
|
||||
|
||||
/**
|
||||
* USE THIS METHOD REPLATE ORIGINAL setDelegate
|
||||
*
|
||||
* @param delegate
|
||||
*/
|
||||
- (void)setCustomDelegate:(NSObject<UIWebViewDelegate>*)delegate;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// UIWebView+AddJavaScriptInterface.m
|
||||
// ObjCAddJSInterface
|
||||
//
|
||||
// Created by wangyaqing on 15/4/8.
|
||||
// Copyright (c) 2015年 billwang1990.github.io. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIWebView+AddJavaScriptInterface.h"
|
||||
#import "YQWebViewProxyDelegate.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
static void *kYQWebViewProxyDelegateKey = &kYQWebViewProxyDelegateKey;
|
||||
|
||||
|
||||
@implementation UIWebView (AddJavaScriptInterface)
|
||||
|
||||
- (void)addJavascriptInterfaces:(NSObject *)interface WithName:(NSString *)name
|
||||
{
|
||||
[[self webViewProxyDelegate] addJavascriptInterfaces:interface WithName:name];
|
||||
}
|
||||
|
||||
- (YQWebViewProxyDelegate*)webViewProxyDelegate
|
||||
{
|
||||
YQWebViewProxyDelegate *retDelegate = nil;
|
||||
|
||||
retDelegate = objc_getAssociatedObject(self, kYQWebViewProxyDelegateKey);
|
||||
|
||||
if (!retDelegate) {
|
||||
retDelegate = [[YQWebViewProxyDelegate alloc]init];
|
||||
objc_setAssociatedObject(self, kYQWebViewProxyDelegateKey, retDelegate, OBJC_ASSOCIATION_RETAIN);
|
||||
}
|
||||
|
||||
return retDelegate;
|
||||
}
|
||||
|
||||
- (void)setCustomDelegate:(NSObject<UIWebViewDelegate> *)delegate
|
||||
{
|
||||
NSCAssert([delegate conformsToProtocol:@protocol(UIWebViewDelegate)], @"must conform UIWebViewDelegate");
|
||||
|
||||
YQWebViewProxyDelegate *proxyDelegate = [self webViewProxyDelegate];
|
||||
[proxyDelegate setDelegate:delegate];
|
||||
|
||||
self.delegate = proxyDelegate;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
120
ObjCAddJSInterface/ObjCAddJSInterface/YQAddJSInterface.js
Normal file
120
ObjCAddJSInterface/ObjCAddJSInterface/YQAddJSInterface.js
Normal file
@@ -0,0 +1,120 @@
|
||||
;(function () {
|
||||
// body...
|
||||
if (window.IKAJS) { return };
|
||||
|
||||
var _callBack = {};
|
||||
var _callBackCount = 1;
|
||||
|
||||
function _resultForCallback(callbackId, retStr) {
|
||||
try {
|
||||
var callback = _callBack[callbackId];
|
||||
if (!callback) return;
|
||||
callback.apply(null,[retStr]);
|
||||
}
|
||||
catch(e) {
|
||||
alert("errot occur");
|
||||
}
|
||||
}
|
||||
|
||||
function _call(obj, functionName, args){
|
||||
|
||||
var formattedArgs = [];
|
||||
|
||||
for (var i = 0, l = args.length; i < l; i++){
|
||||
|
||||
var argType = typeof args[i];
|
||||
var thisArg = args[i];
|
||||
|
||||
if (IKAIs.String(thisArg)) {
|
||||
formattedArgs.push("s");
|
||||
formattedArgs.push(thisArg);
|
||||
}
|
||||
else if(IKAIs.Number(thisArg))
|
||||
{
|
||||
formattedArgs.push("d");
|
||||
formattedArgs.push((args[i]).toString());
|
||||
}
|
||||
else if(IKAIs.Boolean(thisArg))
|
||||
{
|
||||
formattedArgs.push("b");
|
||||
formattedArgs.push((args[i]).toString());
|
||||
}
|
||||
else if( IKAIs.Undefined(thisArg) || IKAIs.Null(thisArg) )
|
||||
{
|
||||
formattedArgs.push("n");
|
||||
formattedArgs.push("NSNull");
|
||||
}
|
||||
else if (IKAIs.Array(thisArg))
|
||||
{
|
||||
formattedArgs.push("a");
|
||||
formattedArgs.push(encodeURIComponent(JSON.stringify(thisArg)));
|
||||
}
|
||||
else if (IKAIs.Function(thisArg))
|
||||
{
|
||||
var key = IKAJS.callBackCount++;
|
||||
_callBack[key.toString()] = thisArg;
|
||||
formattedArgs.push("f");
|
||||
formattedArgs.push(encodeURIComponent(key.toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
formattedArgs.push("o");
|
||||
formattedArgs.push(encodeURIComponent(JSON.stringify(thisArg)));
|
||||
}
|
||||
}
|
||||
|
||||
var argStr = (formattedArgs.length > 0 ? ":" + encodeURIComponent(formattedArgs.join(":")) : "");
|
||||
|
||||
var iframe = document.createElement("IFRAME");
|
||||
iframe.style.display = 'none'
|
||||
iframe.setAttribute("src", "ika-js-scheme:" + obj + ":" + encodeURIComponent(functionName) + argStr);
|
||||
document.documentElement.appendChild(iframe);
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
iframe = null;
|
||||
|
||||
var ret = IKAJS.retValue;
|
||||
IKAJS.retValue = undefined;
|
||||
|
||||
if (ret){
|
||||
return decodeURIComponent(ret);
|
||||
}
|
||||
}
|
||||
|
||||
function _inject(obj, methods){
|
||||
window[obj] = {};
|
||||
var jsObj = window[obj];
|
||||
|
||||
for (var i = 0, l = methods.length; i < l; i++){
|
||||
(function (){
|
||||
var method = methods[i];
|
||||
var jsMethod = method.replace(new RegExp(":", "g"), "");
|
||||
jsObj[jsMethod] = function (){
|
||||
return IKAJS.call(obj, method, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
var IKAIs ={
|
||||
types : ["Function", "Array", "Boolean", "Number", "Object", "String", "Undefined", "Null"]
|
||||
};
|
||||
|
||||
for(var i = 0;i < IKAIs.types.length; i++){
|
||||
var typeName = IKAIs.types[i];
|
||||
IKAIs[typeName] = (function(type){
|
||||
return function(obj){
|
||||
return Object.prototype.toString.call(obj) == "[object " + type + "]";
|
||||
}
|
||||
}
|
||||
)(typeName);
|
||||
}
|
||||
|
||||
window.IKAJS = {
|
||||
call : _call,
|
||||
inject : _inject,
|
||||
invokeCallBack : _resultForCallback,
|
||||
callBack : _callBack,
|
||||
callBackCount : _callBackCount
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// YQWebViewProxyDelegate.h
|
||||
// ObjCAddJSInterface
|
||||
//
|
||||
// Created by wangyaqing on 15/4/8.
|
||||
// Copyright (c) 2015年 billwang1990.github.io. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface YQWebViewProxyDelegate : NSObject<UIWebViewDelegate>
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary *registInterFaces;
|
||||
|
||||
- (void) addJavascriptInterfaces:(NSObject*) interface WithName:(NSString*) name;
|
||||
- (void)setDelegate:(id<UIWebViewDelegate>)delegate;
|
||||
|
||||
@end
|
||||
241
ObjCAddJSInterface/ObjCAddJSInterface/YQWebViewProxyDelegate.m
Normal file
241
ObjCAddJSInterface/ObjCAddJSInterface/YQWebViewProxyDelegate.m
Normal file
@@ -0,0 +1,241 @@
|
||||
//
|
||||
// YQWebViewProxyDelegate.m
|
||||
// ObjCAddJSInterface
|
||||
//
|
||||
// Created by wangyaqing on 15/4/8.
|
||||
// Copyright (c) 2015年 billwang1990.github.io. All rights reserved.
|
||||
//
|
||||
|
||||
#import "YQWebViewProxyDelegate.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#define kCustomProtocolScheme @"ika-js-scheme"
|
||||
|
||||
|
||||
@implementation YQWebViewProxyDelegate
|
||||
{
|
||||
__weak NSObject<UIWebViewDelegate> *_realDelegate;
|
||||
}
|
||||
|
||||
- (void)addJavascriptInterfaces:(NSObject *)interface WithName:(NSString *)name
|
||||
{
|
||||
[self.registInterFaces setObject:interface forKey:name];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)registInterFaces
|
||||
{
|
||||
if (!_registInterFaces) {
|
||||
_registInterFaces = [[NSMutableDictionary alloc]init];
|
||||
}
|
||||
return _registInterFaces;
|
||||
}
|
||||
|
||||
- (void)setDelegate:(id<UIWebViewDelegate>)delegate
|
||||
{
|
||||
_realDelegate = delegate;
|
||||
}
|
||||
|
||||
#pragma mark UIWebViewDelegate
|
||||
- (void)webViewDidFinishLoad:(UIWebView *)webView
|
||||
{
|
||||
if ([_realDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
|
||||
[_realDelegate webViewDidFinishLoad:webView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
|
||||
{
|
||||
if ([_realDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
|
||||
[_realDelegate webView:webView didFailLoadWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webViewDidStartLoad:(UIWebView *)webView
|
||||
{
|
||||
if ([_realDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
|
||||
[_realDelegate webViewDidStartLoad:webView];
|
||||
}
|
||||
[self injectObjectForWebView:webView];
|
||||
}
|
||||
|
||||
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
|
||||
{
|
||||
[self injectObjectForWebView:webView];
|
||||
|
||||
NSURL *url = [request URL];
|
||||
|
||||
if ([[url scheme] hasPrefix:kCustomProtocolScheme]) {
|
||||
|
||||
NSArray *components = [[url absoluteString] componentsSeparatedByString:@":"];
|
||||
|
||||
NSString* obj = (NSString*)[components objectAtIndex:1];
|
||||
|
||||
NSString* method = [(NSString*)[components objectAtIndex:2]
|
||||
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSObject* interface = [self.registInterFaces objectForKey:obj];
|
||||
|
||||
SEL selector = NSSelectorFromString(method);
|
||||
NSMethodSignature* sig = [[interface class] instanceMethodSignatureForSelector:selector];
|
||||
|
||||
NSInvocation* invoker = [NSInvocation invocationWithMethodSignature:sig];
|
||||
invoker.selector = selector;
|
||||
invoker.target = interface;
|
||||
|
||||
//An NSInvocation by default does not retain or copy given arguments for efficiency, so each object passed as argument must still live when the invocation is invoked.
|
||||
NSMutableArray *holdOnParam = [[NSMutableArray alloc]init];
|
||||
|
||||
BOOL callAsync = NO;
|
||||
NSString *callBackID = nil;
|
||||
|
||||
if ([components count] > 3){
|
||||
|
||||
NSString *argsAsString = [(NSString*)[components objectAtIndex:3]
|
||||
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSArray* formattedArgs = [argsAsString componentsSeparatedByString:@":"];
|
||||
|
||||
for (NSInteger i = 0, j = 0, l = [formattedArgs count]; i < l; i+=2, j++){
|
||||
|
||||
NSString* type = ((NSString*) [formattedArgs objectAtIndex:i]);
|
||||
NSString* argStr = ((NSString*) [formattedArgs objectAtIndex:i + 1]);
|
||||
|
||||
if ([@"s" isEqualToString:type]){
|
||||
NSString* arg = [argStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
[holdOnParam addObject:arg];
|
||||
[invoker setArgument:&arg atIndex:(j + 2)];
|
||||
}
|
||||
else if([@"d" isEqualToString:type])
|
||||
{
|
||||
NSString* numStr = [argStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
CGFloat arg = [numStr floatValue];
|
||||
[invoker setArgument:&arg atIndex:(j+2)];
|
||||
}
|
||||
else if ([@"b" isEqualToString:type])
|
||||
{
|
||||
NSString* boolStr = [argStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
BOOL arg = [boolStr boolValue];
|
||||
[invoker setArgument:&arg atIndex:(j+2)];
|
||||
}
|
||||
else if ([@"o" isEqualToString:type])
|
||||
{
|
||||
NSString* objStr = [argStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSData *data = [objStr dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data
|
||||
options:0
|
||||
error:nil];
|
||||
[holdOnParam addObject:dic];
|
||||
[invoker setArgument:&dic atIndex:(j+2)];
|
||||
}
|
||||
else if ([@"a" isEqualToString:type])
|
||||
{
|
||||
NSString *arrStr = [argStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSData *data = [arrStr dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSArray *array = [NSJSONSerialization JSONObjectWithData:data
|
||||
options:0
|
||||
error:nil];
|
||||
[holdOnParam addObject:array];
|
||||
[invoker setArgument:&array atIndex:(j+2)];
|
||||
}
|
||||
else if ([@"f" isEqualToString:type])
|
||||
{
|
||||
callAsync = YES;
|
||||
callBackID = [argStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (callAsync) {
|
||||
__weak typeof(self) wSelf = self;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
[invoker invoke];
|
||||
//return the value by using javascript, only support string, now!!!
|
||||
if ([sig methodReturnLength] > 0){
|
||||
NSString* retValue;
|
||||
[invoker getReturnValue:&retValue];
|
||||
[wSelf returnResultFrom:webView callBkId:callBackID args:retValue];
|
||||
}
|
||||
[holdOnParam removeAllObjects];
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
[invoker invoke];
|
||||
if ([sig methodReturnLength] > 0){
|
||||
NSString* retValue;
|
||||
[invoker getReturnValue:&retValue];
|
||||
|
||||
if (retValue == NULL || retValue == nil){
|
||||
[webView stringByEvaluatingJavaScriptFromString:@"IKAJS.retValue=null;"];
|
||||
}else{
|
||||
retValue = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef) retValue, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8));
|
||||
[webView stringByEvaluatingJavaScriptFromString:[@"" stringByAppendingFormat:@"IKAJS.retValue=\"%@\";", retValue]];
|
||||
}
|
||||
}
|
||||
[holdOnParam removeAllObjects];
|
||||
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (!_realDelegate || ![_realDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]){
|
||||
return YES;
|
||||
}
|
||||
|
||||
return [_realDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
|
||||
}
|
||||
|
||||
- (void)injectObjectForWebView:(UIWebView*)webView
|
||||
{
|
||||
if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof IKAJS == 'object'"] isEqualToString:@"true"]) {
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSString *filePath = [bundle pathForResource:@"YQAddJSInterface" ofType:@"js"];
|
||||
NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
|
||||
[webView stringByEvaluatingJavaScriptFromString:js];
|
||||
}
|
||||
|
||||
__block NSMutableString* injection = [[NSMutableString alloc] init];
|
||||
|
||||
[self.registInterFaces enumerateKeysAndObjectsUsingBlock:^(id objectKey, NSObject *obj, BOOL *stop) {
|
||||
|
||||
/*
|
||||
IKAJS.inject("objname", ["mehod1", "method2"]);
|
||||
*/
|
||||
//object name
|
||||
[injection appendString:@"IKAJS.inject(\""];
|
||||
[injection appendString:objectKey];
|
||||
[injection appendString:@"\", ["];
|
||||
|
||||
//object methods
|
||||
unsigned int count = 0;
|
||||
Class thisCls = object_getClass(obj);
|
||||
|
||||
Method *mtdList = class_copyMethodList(thisCls, &count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
[injection appendString:@"\""];
|
||||
[injection appendString:[NSString stringWithUTF8String:sel_getName(method_getName(mtdList[i]))]];
|
||||
[injection appendString:@"\""];
|
||||
|
||||
if (i != count - 1){
|
||||
[injection appendString:@", "];
|
||||
}
|
||||
}
|
||||
|
||||
[injection appendString:@"]);"];
|
||||
|
||||
free(mtdList);
|
||||
}];
|
||||
|
||||
[webView stringByEvaluatingJavaScriptFromString:injection];
|
||||
}
|
||||
|
||||
- (void)returnResultFrom:(UIWebView*)web callBkId:(NSString*)callbackId args:(NSString*)arg;
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[web stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"IKAJS.invokeCallBack(%@,%@)",callbackId,arg]];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
16
ObjCAddJSInterface/UINavigationItem+Addition.h
Normal file
16
ObjCAddJSInterface/UINavigationItem+Addition.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// UINavigationItem+Addition.h
|
||||
// YanJiYou
|
||||
//
|
||||
// Created by ikamobile-ios on 14-5-20.
|
||||
// Copyright (c) 2014年 billwang1990.github.io. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UINavigationItem (Addition)
|
||||
|
||||
- (UIBarButtonItem*)setNavigationBarItemWithImage:(UIImage *)image andTarget:(id)target action:(SEL)action isLeftItem:(BOOL)isLeft;
|
||||
|
||||
- (UIBarButtonItem *)setNavigationBarItemWithTitle:(NSString *)title andTarget:(id)target action:(SEL)action isLeftItem:(BOOL)isLeft;
|
||||
@end
|
||||
63
ObjCAddJSInterface/UINavigationItem+Addition.m
Normal file
63
ObjCAddJSInterface/UINavigationItem+Addition.m
Normal file
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// UINavigationItem+Addition.m
|
||||
// YanJiYou
|
||||
//
|
||||
// Created by ikamobile-ios on 14-5-20.
|
||||
// Copyright (c) 2014年 billwang1990.github.io. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UINavigationItem+Addition.h"
|
||||
|
||||
@implementation UINavigationItem (Addition)
|
||||
|
||||
- (UIBarButtonItem *)setNavigationBarItemWithTitle:(NSString *)title andTarget:(id)target action:(SEL)action isLeftItem:(BOOL)isLeft
|
||||
{
|
||||
UIBarButtonItem *item;
|
||||
|
||||
CGSize constraint = CGSizeMake(CGFLOAT_MAX,24);
|
||||
NSDictionary * tdic = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:17] , NSFontAttributeName,nil];
|
||||
|
||||
CGSize size =[title boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:tdic context:nil].size;
|
||||
|
||||
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[button setFrame:CGRectMake(0, 0, MIN(ceilf(size.width)+3, 100), 30)];
|
||||
[button setTitle:title forState:UIControlStateNormal];
|
||||
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
|
||||
[button.titleLabel setFont:[UIFont systemFontOfSize:17]];
|
||||
|
||||
item = [[UIBarButtonItem alloc] initWithCustomView:button];
|
||||
|
||||
if (isLeft) {
|
||||
self.leftBarButtonItem = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.rightBarButtonItem = item;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
- (UIBarButtonItem *)setNavigationBarItemWithImage:(UIImage *)image andTarget:(id)target action:(SEL)action isLeftItem:(BOOL)isLeft
|
||||
{
|
||||
UIBarButtonItem *item;
|
||||
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 20, 20)];
|
||||
imageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
imageView.clipsToBounds = YES;
|
||||
[imageView setImage:image];
|
||||
UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc]initWithTarget:target action:action];
|
||||
imageView.userInteractionEnabled = YES;
|
||||
[imageView addGestureRecognizer:tapGes];
|
||||
|
||||
item = [[UIBarButtonItem alloc] initWithCustomView:imageView];
|
||||
|
||||
if (isLeft) {
|
||||
self.leftBarButtonItem = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.rightBarButtonItem = item;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
@end
|
||||
@@ -7,9 +7,13 @@
|
||||
//
|
||||
|
||||
#import "ViewController.h"
|
||||
#import "UIWebView+AddJavaScriptInterface.h"
|
||||
#import "UINavigationItem+Addition.h"
|
||||
|
||||
@interface ViewController ()
|
||||
|
||||
@interface ViewController ()<UIWebViewDelegate>
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIWebView *webView;
|
||||
@end
|
||||
|
||||
@implementation ViewController
|
||||
@@ -17,6 +21,17 @@
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
|
||||
[self.webView addJavascriptInterfaces:self WithName:@"ViewController"];
|
||||
[self.webView setCustomDelegate:self];
|
||||
|
||||
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"]isDirectory:NO]]];
|
||||
|
||||
|
||||
[self.navigationItem setNavigationBarItemWithTitle:@"add" andTarget:self action:@selector(tap) isLeftItem:NO];
|
||||
|
||||
// NSURL *url = [NSURL URLWithString:@"http://blog.devtang.com/blog/2015/04/09/ios-weekly-42/"];
|
||||
// [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
@@ -24,4 +39,53 @@
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
- (void)tap
|
||||
{
|
||||
|
||||
[self.navigationController pushViewController:[ViewController new] animated:YES];
|
||||
}
|
||||
|
||||
- (void)testMethod:(id)param
|
||||
{
|
||||
if ([param isKindOfClass:[NSArray class]]) {
|
||||
[param enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||
NSLog(@"%@ is instance of %@ \n", obj, [obj class]);
|
||||
}];
|
||||
}
|
||||
|
||||
if ([param isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *dic = param;
|
||||
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||
NSLog(@"%@ is instance of %@ \n", obj, [obj class]);
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
NSLog(@"call testMethod from js %@", [param description]);
|
||||
}
|
||||
|
||||
- (void)testBool:(BOOL)val
|
||||
{
|
||||
if (val) {
|
||||
NSLog(@"bool val");
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString*)testFloat:(CGFloat)f
|
||||
{
|
||||
NSLog(@"%f",f);
|
||||
|
||||
__block NSString *ret = nil;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
sleep(5);
|
||||
NSLog(@"fire");
|
||||
ret = @"012343356";
|
||||
});
|
||||
|
||||
while (!ret) {
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
15
ObjCAddJSInterface/test.html
Normal file
15
ObjCAddJSInterface/test.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
ViewController.testFloat(1, function(ret){});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<br>
|
||||
|
||||
<h1>少年带朵花</h1>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user