This topic covers common issues and solutions for iOS integration with the mPaaS HTML5 container.
Notes
When initializing the HTML5 container, specify the base class for all HTML5 pages and the base class for the WebView. This enables unified processing across pages.

When frontend developers create offline packages, do not use Chinese characters in paths or file names. Chinese characters cause the client to fail when decompressing the offline package.
The absolute path of each resource in an offline package must not exceed 100 characters. Longer paths cause the client to fail when decompressing the tar package, resulting in a blank page.
Fix HTML5 container positioning offset issues
Positioning offset issues can occur in the mPaaS container. To fix this, update the settings in your app delegate's beforeDidFinishLaunchingWithOptions method:
- (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Skip LBS location
[LBSmPaaSAdaptor sharedInstance].shouldSkipLBSLocation = YES;
.......
}
The H5_json.json file for a preset offline package does not take effect
This is a baseline version limitation. Baseline 10.1.32 supports only the plist format. Baseline 10.1.60 supports both plist and JSON formats.
Get information about installed offline package applications
Use the following code to retrieve installed app information:
NSDictionary *installedApps = [NAMServiceGet() installApps:nil];
Force an update of all offline package information
Use the encapsulated requestAllNebulaApps method to trigger a full update:
[[MPNebulaAdapterInterface shareInstance]requestAllNebulaApps:^(NSDictionary *data, NSError *error) {
}];
Fix the vux-ui pulldown component freeze on scroll in iOS 13
This freeze is caused by a known bug in UIWebview on iOS. You have two options:
Switch to WKWebView. For migration instructions, see Adapt to WKWebView for mPaaS 10.1.60.
Replace the frontend component with one that does not trigger the bug.
View all JavaScript APIs and plugins registered for the current application
Open an HTML5 page and navigate to the Xcode View Hierarchy page. In the lldb console, run the following commands:
View all JavaScript APIs:
po [[PSDService sharedInstance] jsApis]View all registered plugins:
po [[PSDService sharedInstance] plugins]

Get the UIViewController and WebView objects of the current HTML5 page in a JavaScript API or plugin
During execution, a plugin can directly retrieve the event.context parameter, and a JavaScript API can retrieve the context parameter. The PSDContext object exposes all the information and references you need:
Current view controller:
event.currentViewControllerCurrent WebView:
context.currentViewController.psdContentView


Get the WebView of the current page
The WebView of the current HTML5 page is a property of the current view controller (VC). Retrieve it using vc.psdContentView. To get the VC itself inside a JavaScript API or plugin, use the method described in the previous section.
Retrieve the WebView in the viewWillAppear method, not in viewDidLoad. The WebView is not created during viewDidLoad, so calling it there returns nil.

Get the startup parameters passed by the frontend when the current page loads
Retrieve the psdScene.createParam.expandParams property directly from the current VC.

Restrict a JavaScript API to a specific offline package
In the JavaScript API's execution method, retrieve the appId of the offline package that owns the current page, then conditionally execute your logic based on that value.

Intercept a page URL
Create a custom plugin and listen for the proxy request event:
Register the listener:
[PSDProxy addEventListener:kEvent_Proxy_Request_Start_Handler withListener:self useCapture:YES];Handle the interception in the event callback.
else if ([kEvent_Proxy_Request_Start_Handler isEqualToString:event.eventType]
&& [event isKindOfClass:[PSDProxyEvent class]] ){
NSLog(@"-----kNBEvent_Scene_NavigationItem_Right_Setting_Click----");
PSDProxyEvent *proxyEvent = (PSDProxyEvent*) event;
NSMutableURLRequest *redirectReq = proxyEvent.request.mutableCopy;
NSString *appId = event.context.currentSession.createParam.expandParams[@"appId"];
NAMApp *app = [NAMServiceGet() findApp:appId version:nil];
NSString *fallBackUrl = app.fallback_host;
NSString *vhost = app.vhost;;
NSString *url = redirectReq.URL.absoluteString;
NSLog(@"url__%@______fallBackUrl:%@",url,fallBackUrl);
if ([url containsString:@"www.baidu.com"]) {
[proxyEvent preventDefault];
}}
Intercept the URL of the current HTML5 page before it loads
In the base class of the HTML5 page, implement the UIWebView lifecycle delegate method. Listen for the kEvent_Navigation_Start event to intercept the URL before the page loads, then retrieve the WebView and URL to perform the required processing.

Call a JavaScript API from native code
To call a JavaScript API from the native client on the current page, call the following interface on the current VC:

Why does a local preset offline package fail to load?
Cause: The package version and package information do not match.
Solution: When testing a local preset offline package, first disconnect from the network. This prevents the client from pulling an updated package from the server, ensuring the local preset version is loaded.
Then verify that the preset offline package information matches what is configured in the plist file — specifically app_id, version, and main_url.

Why does the client fail to load a new offline package after it is published in the console?
Before troubleshooting, review the update principle of offline packages. A failure can occur at any stage of the offline package rendering process. Work through the following steps in order:
Check whether the client pulled the latest package from the console. In the console logs, search for
bizType: 4to view the Remote Procedure Call (RPC) return result for the full offline package update. Confirm the returned package details match what you published.If step 1 passes, inspect the offline package information in the finish callback for the package load. Verify that the package is the latest version published in the console,
errorisnil, andapp_id,version, andmain_urlare all correct.If step 2 passes, check whether the offline package was successfully decompressed into the sandbox directory. If the package depends on a global resource package, that global resource package must also be present in the sandbox directory.

If the package is not in the sandbox directory, temporarily disable signature verification, delete the app, and run it again. If the package loads normally with signature verification disabled, the private key used to sign the offline package does not match the public key used for verification on the client — update the public key on the client.

If all previous steps pass but the package still fails to load, use Safari to debug the HTML5 page and identify the specific error. Common causes include an incorrect global resource package path or a missing URL for the offline package.

Global resource package fails to load
If Safari debugging confirms the global resource package is failing to load, work through the following steps:
Check whether the global resource package is registered.
If step 1 passes, check whether the package was successfully decompressed into the sandbox directory.

Check whether the resource file paths referenced in the global resource package are valid. Paths must not contain Chinese characters.
Why does an offline package HTML5 page show a blank screen or a 400 error?
A blank screen or 400 error typically means the local offline package failed to load, causing the client to fall back to the online address. If that fallback address does not exist, the page cannot load.
If the offline package failed to load: Follow the troubleshooting steps in Why does the client fail to load a new offline package after it is published in the console?.
If the fallback address is the issue:
Follow the offline package troubleshooting steps above to determine why the client offline package failed to load.
Confirm that the correct offline package version has been generated and uploaded to the console — for both regular offline packages and global resource packages. For instructions, see Generate an offline package.
If a preset offline package fails to use the online fallback address, make sure the preset offline package is also uploaded to the console.
Verify that the
fallback_base_urlin the local preset package information matches thefallback_base_urlin the h5_json.json configuration file downloaded from the console.

-
Verify that the URL formed by concatenating
fallback_base_urlandmain_urlloads correctly in a browser.
Disable the swipe-to-go-back gesture for an HTML5 page
You can disable the gesture from the frontend or from the native HTML5 container base class.
-
From the frontend HTML5 page — call the
setGestureBackJavaScript API. Use this approach when you need to disable the gesture for a specific page only:AlipayJSBridge.call('setGestureBack',{val:false}); -
From the native HTML5 container base class — call the system interface in the
viewDidAppearmethod of the base class and set thegestureBackparameter. Use this approach when you need to disable the gesture for multiple or all HTML5 pages:-(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.options.gestureBack = NO; if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { self.navigationController.interactivePopGestureRecognizer.enabled = NO; } }
Determine if the current page is in a Mini Program
Retrieve the session of the current page and call the isTinyAppWithSession interface:
PSDSession *session = self.psdSession;
BOOL isTinyApp = [NBUtils isTinyAppWithSession:session];
Pass custom parameters to an HTML5 page
The method depends on the caller and destination. The following scenarios are supported:
-
Native to HTML5 — pass parameters in the
startH5ViewControllerWithParamscall:[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"key1":@"value1"}]; -
Native to offline package — pass parameters in the
startH5ViewControllerWithNebulaAppcall:[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithNebulaApp:@{@"appId":@"70000000",@"param":@{@"key2":@"value2"}}]; -
HTML5 to HTML5 — when calling
pushWindow, write custom parameters inpassData. On the destination page, retrieve them withAlipayJSBridge.startupParams:AlipayJSBridge.call('pushWindow', { // The URL of the page to open url: 'https://m.taobao.com/', // Configuration parameters for opening the page param: { readTitle: true, // Automatically read the title showOptionMenu: false, // Hide the right-side menu transparentTitle:'always', }, // Optional. Used to pass parameters to the new page. // On the new page, you can use AlipayJSBridge.startupParams to get passData passData: { key1: "key1Value", key2: "key2Value" } }); -
HTML5 to offline package — when calling the
startAppJavaScript API, write custom parameters inparam:AlipayJSBridge.call('startApp', { appId: '70000000', param: { key1:'value1' } }, function(result) { // noop });
Get passed parameters on an HTML5 page
There are two retrieval paths:
-
From the frontend — use the
startupParamsmethod to retrieve the startup parameters of the current page:AlipayJSBridge.startupParams -
From native code — retrieve parameters through the VC object of the current page:
// Startup parameters of the current page NSDictionary *expandParams = self.psdScene.createParam.expandParams; NSLog(@"[mpaas] expandParams: %@", expandParams);
Intercept a JavaScript API call
Create a custom plugin and listen for the invocation event:
Listen for the event:
kEvent_Invocation_Event_Start-
In the event handler, retrieve the JavaScript API name, passed parameters, and any other required information:
else if([kEvent_Invocation_Event_Start isEqualToString:event.eventType]) { PSDInvocationEvent * invocationEvent = (PSDInvocationEvent *)event; NSString * apiName = invocationEvent.invocationName; if([apiName isEqualToString:@"setOptionMenu"] || [apiName isEqualToString:@"showOptionMenu"] ) { NSLog(@"wwww"); } }






