Happy New Year !
In the last post, I introduced how to produce a standalone executable application for Forge Viewer. At that time, I was also looking for the way that can apply to mobile OS. Apache Cordova is one of the approaches I was investigating. The practice proved my choice is correct :) By Cordova, the app is successfully running on my iPhone (no internet connection).
Quoted from Apache Cordova : Cordova is an open-source mobile development framework. It allows you to use standard web technologies - HTML5, CSS3, and JavaScript for cross-platform development. Applications execute within wrappers targeted to each platform, and rely on standards-compliant API bindings to access each device's capabilities such as sensors, data, network status, etc.
The usage of Cordova is very clear and easy, while I learnt a lot when playing with it such as configuring the environments with necessary packages, debugging a hybrid app with JavaScript, diagnosing the issues of Forge Viewer that is specific in such scenario etc. I'd like to share the main steps/tricks. The whole demo source project is available at:
https://github.com/xiaodongliang/Forge-Viewer-iOS-Cordova
1. Follow the steps to create the app. I'd suggest to test in Browser mode firstly. It can help you to figure out generic issues that are not related with the mobile app. Once it works, the browser will display a helloworld webpage
2. On Extract tool of Forge Viewer, upload your model file and follow those steps to get the offline package. Unzip the package
3. Create a new folder in the Cordova project root\www\ (say ‘Forge’), copy the contents of the package in #2 to this folder. The files index.exe and index.bat are unnecessary for this project. You can remove them.
4. Copy some headers from root\www\index.html to root\www\Forge\index.html. Cordova sets strict security policy by default. For demo only, I simply commented out those headers. In reality, please make sure to set appropriate security policy.
5. Update Cordova project root\config.xml to direct to Forge\index.html
< content src="Forge/index.html" />
6. Build and run with browser again, it will run like the webpage below. That means the Viewer has been successfully integrated with the browser mode. you might need to diagnose in console if there is any issues that caused any failures.
7. Now, follow the steps on Cordova to add platform of iOS. Run it on the Emulator. The deployment of the page is shown up, but the model is not loaded to the viewer. After some debugging I finally found when Forge Viewer tries to load the offline dataset, it submits an XHR to request the resource in the local storage. In the native browser mode, this will return HTTP response = 200 if succeeded, while on the hybrid mode, it returns HTTP response = 0. So the initialization of loading model will fail. The relevant codes are within lmvworker.min.js. After adding the condition, rebuild the app, and run it, the model is now loaded successfully.
8. Because of the size of a mobile, I removed the sibling panel and other text areas of the demo page, in order to see the viewer only. In Emulator, the app is looked like:
8. If everything works well, you could follow the steps on Apple to distribute the app to the real device.
In reality, it will be bad, even not allowed by App Store if packaging an app with huge model dataset. So the app should provide the channel either loading model from local storage (assume the model data set has been copied to the device by other ways), or downloading the dataset when internet is available. Actually, the solution in this blog is mainly for those scenarios when internet is not available such as construction field. With the solution, a worker can still manage the model in offline, and sync the management with administration platform when internet is on.
I was also investigating the possibility to make app of Android. Unfortunately, from some discussions on internet, it seems WebView of Android has not supported WebGL nicely. Even though I tried to build the Android app by CrossWalker, Forge Viewer still failed to initialize THREE.js render. If you know about the tricks, I'd appreciate if you could share the experience.