gpt4 book ai didi

javascript - 从 Javascript 调用 iOS Webview 委托(delegate)未触发

转载 作者:行者123 更新时间:2023-11-28 08:17:51 24 4
gpt4 key购买 nike

我在基于 iOS 增强现实的 iOS 项目中从 Metaio 3rd party sdk 获取了 Logic.js 文件。此 .JS 文件由 Metaio 创建者创建。

我正在修改此文件以调用我的 iOS native Web View 。基本上,我想从这个 .JS 文件调用 iOS native View 。

下面是iOS项目中使用的Logic.js文件。使用 window.location 我尝试从此 .JS 文件调用 UIWebview 委托(delegate)。

var methodExists = function (object, method) {
return typeof object !== 'undefined' && typeof method === 'function';
};

arel.sceneReady(function() {

var scenario = {};
scenario.objectName = "scenario";
scenario.contents = []; // Array of all contents in this AR scenario
scenario.trackables = []; // Array of all trackables in this AR scenario
scenario.scenes = []; // Array of all scenes in this AR scenario
scenario.googleAnalytics = null;
scenario.currentScene = null;
scenario.currentExperience360 = null;
scenario.instantTrackingMode = false; // True if instant tracking is currently running
scenario.currentTrackingConfigPathOrIdentifier = "html/resources/TrackingData.zip";

scenario.addObject = function (object) {
arel.Debug.log("scenario.addObject(" + object.objectName + ")");
this.registerObject(object);
arel.Scene.addObject(object);
};

scenario.registerObject = function (object) {
arel.Debug.log("scenario.registerObject(" + object.objectName + ")");
arel.Events.setListener(object, this.objectEventsCallback, scenario);
};

scenario.groupID = 0;
scenario.getNewGroupID = function () {
this.groupID++;
return this.groupID;
};

scenario.getTrackable = function (identifier) {
arel.Debug.log("scenario.getTrackable(" + identifier + ")");
var i;
var trackable = null;
if (!identifier || identifier === "") {
arel.Debug.log("scenario.getTrackable(): Warning - identifier is empty, returning null");
return trackable;
}
var allTrackables = this.trackables;
for (i = 0; i < allTrackables.length; ++i) {
trackable = allTrackables[i];
if (trackable.objectName == identifier) {
return trackable;
}
if (trackable.cosName == identifier) {
return trackable;
}
if (trackable.cosID == identifier) {
return trackable;
}
}
arel.Debug.log("scenario.getTrackable(" + identifier + "): Error - could not correlate the given identifier to any known trackable.");
return null;
};

scenario.sceneCallback = function (type, result) {
if (!type) {
return;
}
switch (type) {
case arel.Events.Scene.ONTRACKING:
this.onTrackingChanged(result);
break;
case arel.Events.Scene.ONVISUALSEARCHRESULT:
break;
case arel.Events.Scene.ONREADY:
break;
case arel.Events.Scene.ONLOAD:
case arel.Events.Scene.ONLOCATIONUPDATE:
default:
break;
}
};

scenario.objectEventsCallback = function (object, type, params) {
switch (type) {
case arel.Events.Object.ONREADY:
if (methodExists(object, object.onLoaded)) {
object.onLoaded();
}
break;
case arel.Events.Object.ONTOUCHSTARTED:
if (this.googleAnalytics) {
this.googleAnalytics.logUIInteraction(arel.Plugin.Analytics.Action.TOUCHSTARTED, object.getID());
}
break;
case arel.Events.Object.ONTOUCHENDED:
if (this.googleAnalytics) {
this.googleAnalytics.logUIInteraction(arel.Plugin.Analytics.Action.TOUCHENDED, object.getID());
}
break;
case arel.Events.Object.ONINVISIBLE:
case arel.Events.Object.ONVISIBLE:
case arel.Events.Object.ONANIMATIONENDED:
case arel.Events.Object.ONMOVIEENDED:
case arel.Events.Object.ONLOAD:
case arel.Events.Object.ONROTATED:
case arel.Events.Object.ONSCALED:
case arel.Events.Object.ONTRANSLATED:
default:
break;
}
};

scenario.onTrackingChanged = function (trackingValuesList) {
if (trackingValuesList.length === 0) {
arel.Debug.log("scenario.onTrackingChanged: Error - list of tracking values is empty, this should be impossible.");
return;
}
var i, trackingValues, cosName, cosID, trackable, trackingMethod, gaTrackingMethod;
for (i = 0; i < trackingValuesList.length; i++) {
trackingValues = trackingValuesList[i];
trackable = null;
cosName = trackingValues.getCoordinateSystemName();
cosID = trackingValues.getCoordinateSystemID();
// Try to find the trackable by its COS name first. If that fails, try the COS ID.
if (cosName && cosName !== "") {
trackable = this.getTrackable(cosName);
}
if (trackable === null && cosID) {
trackable = this.getTrackable(cosID);
}
if (trackable === null) {
arel.Debug.log("onTrackingChanged: Error - Can't find a trackable matching COS name '" + cosName + "' or COS ID '" + cosID + "'");
return;
}
else {
// The cosID 1 is strictly reserved for the 360 experience if it is running.
if (scenario.currentExperience360 && cosID === 1) {
return;
}
}

switch (trackingValues.getState()) {
case arel.Tracking.STATE_NOTTRACKING:
arel.Debug.log("onTrackingChanged: " + trackable.objectName + " is not tracking");
if (methodExists(trackable, trackable.onTrackingLost)) {
trackable.onTrackingLost(trackingValues);
}
break;
case arel.Tracking.STATE_TRACKING:
arel.Debug.log("onTrackingChanged: " + trackable.objectName + " is tracking");
if (methodExists(trackable, trackable.onDetected)) {
trackable.onDetected();
}
if (methodExists(trackable, trackable.onTracked)) {
trackable.onTracked(trackingValues);
}
if (this.googleAnalytics) {
trackingMethod = trackingValues.getType();
gaTrackingMethod = this.googleAnalytics.trackingTypeToAnalyticsType(trackingMethod);
this.googleAnalytics.logTrackingEvent(gaTrackingMethod, arel.Plugin.Analytics.Action.STATE_TRACKING, cosID, cosName);
}
break;
case arel.Tracking.STATE_EXTRAPOLATED:
case arel.Tracking.STATE_INITIALIZED:
case arel.Tracking.STATE_REGISTERED:
default:
break;
}
}
};


scenario.startInstantTracking = function () {
arel.Debug.log("scenario.startInstantTracking()");
if (this.instantTrackingMode) {
return;
}
this.instantTrackingMode = true;

if (scenario.currentExperience360) {
scenario.currentExperience360.hide();
}

// Iterate over all trackables, simulate an onTrackingLost() for all those which are currently tracking.
var i, trackable;
for (i = 0; i < this.trackables.length; ++i) {
trackable = this.trackables[i];
if (trackable.isCurrentlyTracking && trackable != userDevice) {
if (methodExists(trackable, trackable.onTrackingLost)) {
trackable.onTrackingLost();
}
}
}
arel.Scene.startInstantTracking(arel.Tracking.INSTANT2D);
if (methodExists(this, this.onStartInstantTracking)) {
this.onStartInstantTracking();
}
};

scenario.stopInstantTracking = function () {
arel.Debug.log("scenario.stopInstantTracking()");
if (!this.instantTrackingMode) {
return;
}
this.instantTrackingMode = false;
if (methodExists(instantTracker, instantTracker.onTrackingLost)) {
instantTracker.onTrackingLost();
}
this.setTrackingConfiguration(this.currentTrackingConfigPathOrIdentifier);
if (methodExists(this, this.onStopInstantTracking)) {
this.onStopInstantTracking();
}
};

scenario.skipTrackingInitialization = function () {
arel.Debug.log("scenario.skipTrackingInitialization()");
arel.Scene.sensorCommand("initialize", "", function(a) {});
if (methodExists(this, this.onSkipTrackingInitialization)) {
this.onSkipTrackingInitialization();
}
};

scenario.reloadTrackingConfiguration = function () {
arel.Debug.log("scenario.reloadTrackingConfiguration()");
this.setTrackingConfiguration(this.currentTrackingConfigPathOrIdentifier);
if (methodExists(this, this.onReloadTrackingConfiguration)) {
this.onReloadTrackingConfiguration();
}
};

scenario.setTrackingConfiguration = function (trackingConfigPathOrIdentifier) {
// Iterate over all trackables, simulate an onTrackingLost() for all those which are currently tracking.
var i, trackable;
for (i = 0; i < this.trackables.length; ++i) {
trackable = this.trackables[i];
if (trackable.isCurrentlyTracking && trackable != userDevice) {
if (methodExists(trackable, trackable.onTrackingLost)) {
trackable.onTrackingLost();
}
}
}

// Set the new tracking configuration.
arel.Scene.setTrackingConfiguration(trackingConfigPathOrIdentifier);
};

scenario.onStartup = function () {
arel.Debug.log("Welcome to the 'HouseProject' Augmented Reality experience.");

arel.Events.setListener(arel.Scene, scenario.sceneCallback, scenario);

if (google_analytics_id) {
arel.Debug.log("Google Analytics is enabled. Your account ID is: " + google_analytics_id);
arel.Debug.log("The event sampling rate is: arel.Plugin.Analytics.EventSampling.ONCE");
scenario.googleAnalytics = new arel.Plugin.Analytics(google_analytics_id, arel.Plugin.Analytics.EventSampling.ONCE, "");
} else {
arel.Debug.log("Note: No Google Analytics ID is set - Google Analytics will be disabled.");
}

if (methodExists(scenario, scenario.onLoaded)) {
scenario.onLoaded();
}

// The following contents have been defined in the index.xml file, therefore we need to register them
// and call their onLoaded() event manually.
scenario.registerObject(model6);
if (methodExists(model6, model6.onLoaded)) {
model6.onLoaded();
}
scenario.registerObject(model7);
if (methodExists(model7, model7.onLoaded)) {
model7.onLoaded();
}


if (methodExists(userDevice, userDevice.onLoaded)) {
userDevice.onLoaded();
}

// All objects have been defined, so start the AR experience by calling each trackable's .onLoaded() method.
var i, trackable;
for (i = 0; i < scenario.trackables.length; ++i) {
trackable = scenario.trackables[i];
if (methodExists(trackable, trackable.onLoaded)) {
trackable.onLoaded();
}
}

// Call the first scene's display() once to make sure that the content of that scene is initially visible.
scene1.display();
};


var scene1 = {};
scenario.scenes.push(scene1);
scene1.objectName = "scene1";

scene1.display = function () {
arel.Debug.log(this.objectName + ".display()");

if (scenario.currentScene == this) {
return;
}

// Iterate over all trackables, simulate an onTrackingLost() for all those which are currently tracking.
var trackingTrackables = [];
var i, trackable;
for (i = 0; i < scenario.trackables.length; ++i) {
trackable = scenario.trackables[i];
if (trackable.isCurrentlyTracking) {
// The instant tracker should be excluded from the tracking ones because it will be stopped later on.
if (trackable !== instantTracker) {
trackingTrackables.push(trackable);
}
if (methodExists(trackable, trackable.onTrackingLost)) {
trackable.onTrackingLost();
}
}
}

// In case any instant tracking is currently running, stop it before switching to the other scene.
scenario.stopInstantTracking();

var previousExperience360 = null;
if (scenario.currentExperience360) {
previousExperience360 = scenario.currentExperience360;
scenario.currentExperience360.hide();
}

scenario.currentScene = this;

// Iterate over all tracking trackables again, this time simulating an onDetected() and onTracked() event
// for all those which are currently tracking.
for (i = 0; i < trackingTrackables.length; ++i) {
trackable = trackingTrackables[i];
if (methodExists(trackable, trackable.onDetected)) {
trackable.onDetected();
}
if (methodExists(trackable, trackable.onTracked)) {
trackable.onTracked(trackable.currentTrackingValues);
}
}

if (previousExperience360) {
// A 360 was displayed in the previous scene, we now need to check whether any 360 in the new scene
// is triggered by the same trackable. If so, that 360 should be displayed.
var i, content;
for (i = 0; i < scenario.contents.length; ++i) {
content = scenario.contents[i];
if (content.type == "Experience360" && content.scene == this &&
content.associatedTrackable == previousExperience360.associatedTrackable) {
content.display();
break;
}
}
}

if (methodExists(this, this.onDisplayed)) {
this.onDisplayed();
}
};


var instantTracker = {};
scenario.trackables.push(instantTracker);
instantTracker.objectName = "instantTracker";
instantTracker.cosName = "InstantTracker";
instantTracker.cosID = "1";
instantTracker.isCurrentlyTracking = false;
instantTracker.currentTrackingValues = null;
instantTracker.onTracked = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTracked()");
this.isCurrentlyTracking = true;
this.currentTrackingValues = trackingValues;
};

instantTracker.onTrackingLost = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTrackingLost()");
this.isCurrentlyTracking = false;
this.currentTrackingValues = null;
};


var pattern2 = {};
scenario.trackables.push(pattern2);
pattern2.objectName = "pattern2";
pattern2.cosName = "Home1_1";
pattern2.cosID = "1";
pattern2.isCurrentlyTracking = false;
pattern2.currentTrackingValues = null;
pattern2.onTracked = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTracked()");
this.isCurrentlyTracking = true;
this.currentTrackingValues = trackingValues;
// Try to call native from here

window.location = "js-call:" + "myObjectiveCFunction";

model6.display();
model6.play("Default Take", false);

};

pattern2.onTrackingLost = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTrackingLost()");
this.isCurrentlyTracking = false;
this.currentTrackingValues = null;
model6.hide();
};


var pattern3 = {};
scenario.trackables.push(pattern3);
pattern3.objectName = "pattern3";
pattern3.cosName = "Home2_2";
pattern3.cosID = "2";
pattern3.isCurrentlyTracking = false;
pattern3.currentTrackingValues = null;
pattern3.onTracked = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTracked()");
this.isCurrentlyTracking = true;
this.currentTrackingValues = trackingValues;
model7.display();
model7.play("Default Take", false);
};

pattern3.onTrackingLost = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTrackingLost()");
this.isCurrentlyTracking = false;
this.currentTrackingValues = null;
model7.hide();
};


var userDevice = {};
userDevice.isCurrentlyTracking = true; // The pose of the user's device is always tracked...
scenario.trackables.push(userDevice);
userDevice.objectName = "userDevice";
userDevice.cosName = "Device";
userDevice.cosID = "-1";
userDevice.onTracked = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTracked()");
this.isCurrentlyTracking = true;
this.currentTrackingValues = trackingValues;
};

userDevice.onTrackingLost = function (trackingValues) {
arel.Debug.log(this.objectName + ".onTrackingLost()");
this.isCurrentlyTracking = false;
this.currentTrackingValues = null;
};

// Kick-off the AR experience by calling the scenario's onStartup() method as soon as AREL is ready
scenario.onStartup();
});

在 iOS 端:UIWebview 放置在 View Controller 中,及其委托(delegate)方法来获取 Javascript 调用。

    - (BOOL)webView:(UIWebView *)webView2
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {

NSLog(@"Inside WebView");

NSString *requestString = [[request URL] absoluteString];

if ([[[request URL] absoluteString] hasPrefix:@"js-call:"]) {

NSLog(@"Call from Javascript");
return NO;
}

// Accept this location change
return YES;

}

这是在头文件中创建的 webview 对象:

#import "MetaioSDKViewController.h"
#import <metaioSDK/GestureHandlerIOS.h>
#import <metaioSDK/IARELInterpreterIOS.h>

// forward declarations
@class EAGLView;

@interface ARELViewController : MetaioSDKViewController<UIGestureRecognizerDelegate, IARELInterpreterIOSDelegate, UIWebViewDelegate>
{
metaio::IARELInterpreterIOS* m_ArelInterpreter;
GestureHandlerIOS* m_pGestureHandlerIOS;
NSString* m_arelFile;
}

@property (nonatomic, retain) IBOutlet UIWebView* m_arelWebView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil instructions:(NSString *)arelTutorialConfig;

- (void) onSDKReady;

@end

在 .mm 中它的设置:(注意:Interface Builder 也已设置 Delegate)

- (void)viewDidLoad {
[super viewDidLoad];

m_arelWebView.delegate = self;

}

当此功能执行时,根本不会从 Javascript 调用此函数。

有人可以告诉我这可能是什么原因吗?为什么 Javascript 调用没有触发此 native webview 委托(delegate)。

谢谢!

最佳答案

我也遇到了同样的问题我假设您已经使用过 Native Bridge 库:https://github.com/ochameau/NativeBridge .

该库让您实现

- (BOOL)webView:(UIWebView *)webView2 shouldStartLoadWithRequest:(NSURLRequest *)request      navigationType:(UIWebViewNavigationType)navigationType

方法,但在MetaioCloudPluginViewController(ARELViewController的父类(super class))中,您可以看到您需要实现:

/** Overwrite this method if you want to be able to handle custom URL schemes that are launched
* from your channel
* \param request the request that is being sent
*
* You can use it like this:
* NSURL* theURL = [request mainDocumentURL];
* NSString* absoluteString = [theURL absoluteString];
* if( [[absoluteString lowercaseString] hasPrefix:@"yourapp://"] )
* {
* // do something
* return NO;
* }
* return YES;
*/
- (BOOL) shouldStartLoadWithRequest:(NSURLRequest *) request;

你只需要使用它

关于javascript - 从 Javascript 调用 iOS Webview 委托(delegate)未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23388158/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com