Skip to content

Commit c105cb3

Browse files
feat(ww): harden mobileproxy integration (#411)
* fix(ww): harden mobileproxy integration * ios error handling * android toast * fix typo * don't show error: just retry and gracefully do nothing * make port dynamic * pass sdk version * Update build_sdk_mobileproxy.sh * Update build_sdk_mobileproxy.sh * Update AppDelegate.swift * fix issue
1 parent ad7a842 commit c105cb3

File tree

6 files changed

+81
-40
lines changed

6 files changed

+81
-40
lines changed

x/examples/website-wrapper-app/.scripts/build_sdk_mobileproxy.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
# limitations under the License.
1616

1717
PLATFORM="$1"
18+
TAG="${2:-"x/v0.0.1"}"
1819

19-
git clone https://github.com/Jigsaw-Code/outline-sdk.git output/outline-sdk
20+
git clone --depth 1 --branch "${TAG}" https://github.com/Jigsaw-Code/outline-sdk.git output/outline-sdk
2021
cd output/outline-sdk/x
2122
go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
2223

x/examples/website-wrapper-app/wrapper_app_project/.scripts/build.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const DEFAULT_SMART_DIALER_CONFIG = {
4747
export default async function main(
4848
{
4949
platform,
50+
sdkVersion = "x/v0.0.1",
5051
entryDomain = "www.example.com",
5152
navigationUrl,
5253
smartDialerConfig = DEFAULT_SMART_DIALER_CONFIG,
@@ -56,7 +57,7 @@ export default async function main(
5657
if (!fs.existsSync(SDK_MOBILEPROXY_OUTPUT_DIR)) {
5758
console.log(`Building the Outline SDK mobileproxy library for ${platform}...`);
5859

59-
await promisify(exec)(`npm run build:sdk_mobileproxy ${platform}`);
60+
await promisify(exec)(`npm run build:sdk_mobileproxy ${platform} ${sdkVersion}`);
6061
}
6162

6263
const sourceFilepaths = await glob(

x/examples/website-wrapper-app/wrapper_app_project/template/android/app/src/main/java/org/getoutline/pwa/MainActivity.kt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ class MainActivity : BridgeActivity() {
1717
super.onCreate(savedInstanceState)
1818

1919
if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) {
20+
if (!this.tryProxy()) {
21+
// try one more time
22+
this.tryProxy()
23+
}
24+
}
25+
}
26+
27+
override fun onDestroy() {
28+
this.proxy?.stop(3000)
29+
this.proxy = null
30+
31+
super.onDestroy()
32+
}
33+
34+
private fun tryProxy(): Boolean {
35+
try {
2036
this.proxy = Mobileproxy.runProxy(
2137
"127.0.0.1:0",
2238
Mobileproxy.newSmartStreamDialer(
@@ -41,13 +57,10 @@ class MainActivity : BridgeActivity() {
4157
},
4258
{}
4359
)
60+
} catch (e: Exception) {
61+
return false
4462
}
45-
}
46-
47-
override fun onDestroy() {
48-
this.proxy?.stop(3000)
49-
this.proxy = null
5063

51-
super.onDestroy()
64+
return true
5265
}
5366
}
Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
1-
import UIKit
21
import Capacitor
32
import Mobileproxy
3+
import UIKit
44

55
@UIApplicationMain
66
class AppDelegate: UIResponder, UIApplicationDelegate {
77

88
var window: UIWindow?
9-
9+
1010
private var proxy: MobileproxyProxy? = nil
1111

12-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
12+
func application(
13+
_ application: UIApplication,
14+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
15+
) -> Bool {
1316

14-
self.window?.rootViewController = OutlineBridgeViewController()
17+
self.resetViewController()
1518

1619
return true
1720
}
1821

1922
func applicationDidBecomeActive(_ application: UIApplication) {
20-
var dialerError: NSError?
21-
if let dialer = MobileproxyNewSmartStreamDialer(
22-
MobileproxyNewListFromLines(Config.domainList),
23-
Config.smartDialer,
24-
MobileproxyNewStderrLogWriter(),
25-
&dialerError
26-
) {
27-
var proxyError: NSError?
28-
self.proxy = MobileproxyRunProxy(
29-
"127.0.0.1:8080",
30-
dialer,
31-
&proxyError
32-
)
23+
if !self.tryProxy() {
24+
// try one more time
25+
self.tryProxy()
3326
}
3427
}
3528

@@ -40,16 +33,57 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
4033
}
4134
}
4235

43-
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
36+
func application(
37+
_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]
38+
) -> Bool {
4439
// Called when the app was launched with a url. Feel free to add additional processing here,
4540
// but if you want the App API to support tracking app url opens, make sure to keep this call
4641
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
4742
}
4843

49-
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
44+
func application(
45+
_ application: UIApplication, continue userActivity: NSUserActivity,
46+
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
47+
) -> Bool {
5048
// Called when the app was launched with an activity, including Universal Links.
5149
// Feel free to add additional processing here, but if you want the App API to support
5250
// tracking app url opens, make sure to keep this call
53-
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
51+
return ApplicationDelegateProxy.shared.application(
52+
application, continue: userActivity, restorationHandler: restorationHandler)
53+
}
54+
55+
@discardableResult
56+
private func tryProxy() -> Bool {
57+
var error: NSError?
58+
if let dialer = MobileproxyNewSmartStreamDialer(
59+
MobileproxyNewListFromLines(Config.domainList),
60+
Config.smartDialer,
61+
MobileproxyNewStderrLogWriter(),
62+
&error
63+
) {
64+
if error != nil {
65+
return false
66+
}
67+
68+
self.proxy = MobileproxyRunProxy(
69+
"127.0.0.1:0",
70+
dialer,
71+
&error
72+
)
73+
74+
self.resetViewController()
75+
76+
Config.proxyPort = String(self.proxy?.port() ?? 0)
77+
78+
if error != nil {
79+
return false
80+
}
81+
}
82+
83+
return true
84+
}
85+
86+
private func resetViewController() {
87+
self.window?.rootViewController = OutlineBridgeViewController()
5488
}
5589
}

x/examples/website-wrapper-app/wrapper_app_project/template/ios/App/App/Config.swift.handlebars

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ import Foundation
33
struct Config {
44
static var domainList: String = "{{domainList}}"
55
static var smartDialer: String = "{{{smartDialerConfig}}}"
6+
static var proxyHost: String = "127.0.0.1"
7+
static var proxyPort: String = "0"
68
}

x/examples/website-wrapper-app/wrapper_app_project/template/ios/App/App/OutlineBridgeViewController.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
1-
//
2-
// OutlineBridgeViewController.swift
3-
// App
4-
//
5-
// Created by Daniel LaCosse on 10/9/24.
6-
//
7-
81
import UIKit
92
import Capacitor
103

114
class OutlineBridgeViewController: CAPBridgeViewController {
12-
private let proxyHost: String = "127.0.0.1"
13-
private let proxyPort: String = "8080"
14-
155
override func webView(with frame: CGRect, configuration: WKWebViewConfiguration) -> WKWebView {
166
if #available(iOS 17.0, *) {
177
let endpoint = NWEndpoint.hostPort(
18-
host: NWEndpoint.Host(self.proxyHost),
19-
port: NWEndpoint.Port(self.proxyPort)!
8+
host: NWEndpoint.Host(Config.proxyHost),
9+
port: NWEndpoint.Port(Config.proxyPort)!
2010
)
2111
let proxyConfig = ProxyConfiguration.init(httpCONNECTProxy: endpoint)
2212

0 commit comments

Comments
 (0)