importmobileproxy.*valdialer=StreamDialer("split:3")// Use port zero to let the system pick an open port for you.valproxy=Mobileproxy.runProxy("localhost:0",dialer)// Configure your networking library using proxy.host() and proxy.port() or proxy.address().// ...// Stop running the proxy.proxy.stop()
iOS
importMobileproxyletdialer=MobileproxyStreamDialer("split:3")// Use port zero to let the system pick an open port for you.letproxy=MobileproxyRunProxy("localhost:0",dialer)// Configure your networking library using proxy.host() and proxy.port() or proxy.address().// ...// Stop running the proxy.proxy.stop()
Smart Proxy:Smart Proxy 可根据指定的测试网域动态选择 DNS 和 TLS 策略。您需要以 YAML 格式指定配置策略(示例)。
Android
valtestDomains=Mobileproxy.newListFromLines("www.youtube.com\ni.ytimg.com")valstrategiesConfig="..."// Config YAML.valdialer=Mobileproxy.newSmartStreamDialer(testDomains,strategiesConfig,Mobileproxy.newStderrLogWriter())// Use port zero to let the system pick an open port for you.valproxy=Mobileproxy.runProxy("localhost:0",dialer)// Configure your networking library using proxy.host() and proxy.port() or proxy.address().// ...// Stop running the proxy.proxy.stop()
iOS
importMobileproxyvardialerError:NSError?lettestDomains=MobileproxyNewListFromLines("www.youtube.com\ni.ytimg.com")letstrategiesConfig="..."// Config YAML.letdialer=MobileproxyNewSmartStreamDialer(testDomains,strategiesConfig,MobileproxyNewStderrLogWriter(),&dialerError)varproxyError:NSError?// Use port zero to let the system pick an open port for you.MobileproxyRunProxy("localhost:0",dialer,&proxyError)// Configure your networking library using proxy.host() and proxy.port() or proxy.address().// ...// Stop running the proxy.proxy.stop()
ProxyController.getInstance().setProxyOverride(ProxyConfig.Builder().addProxyRule(this.proxy!!.address()).build(),{},// execution context for the following callback - do anything needed here once the proxy is applied, like refreshing web views{}// callback to be called once the ProxyConfig is applied)
[null,null,["最后更新时间 (UTC):2025-07-11。"],[],[],null,["# Add Outline SDK to your mobile app\n\nThis document outlines how to integrate the Outline SDK into your mobile\napplications, focusing on the `MobileProxy` library for simplified local proxy\nmanagement.\n\n`MobileProxy` is a Go-based library designed to streamline the integration of\nproxy functionalities into mobile apps. It utilizes [Go\nMobile](https://go.dev/wiki/Mobile) to generate mobile libraries, enabling you\nto configure your app's networking libraries to route traffic through a local\nproxy.\n\n**App without MobileProxy**\n\n**App with MobileProxy**\n\nStep 1: Building MobileProxy mobile libraries\n---------------------------------------------\n\nUse [gomobile](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile) to compile\nthe Go code into libraries for Android and iOS.\n\n1. Clone the Outline SDK repository:\n\n git clone https://github.com/Jigsaw-Code/outline-sdk.git\n cd outline-sdk/x\n\n2. Build the Go Mobile binaries with [`go\n build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies):\n\n go build -o \"$(pwd)/out/\" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind\n\n #### Adding Psiphon Support\n\n You can add support to use the [Psiphon](https://psiphon.ca/) network by\n following these extra steps:\n - Contact the Psiphon team to obtain a config that gives you access to their network. This may require a contract.\n - Add the received Psiphon config to the `fallback` section of your `SmartDialer` config.\n - Build the Mobile Proxy using the `-tags psiphon` flag:\n\n go build -tags psiphon -o \"$(pwd)/out/\" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind\n\n The `-tags psiphon` flag is required because the Psiphon codebase is\n licensed under the GPL, which can impose license restrictions on your own\n code. You may want to consider obtaining a special license from them.\n3. Generate mobile libraries and add them to your project:\n\n ### Android\n\n PATH=\"$(pwd)/out:$PATH\" gomobile bind -ldflags='-s -w' -target=android -androidapi=21 -o \"$(pwd)/out/mobileproxy.aar\" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy\n\n In Android Studio select **File \\\u003e Import Project...** to import the generated `out/mobileproxy.aar` bundle. For more help see Go Mobile's [Building and deploying to Android](https://go.dev/wiki/Mobile#building-and-deploying-to-android-1).\n\n ### iOS\n\n PATH=\"$(pwd)/out:$PATH\" gomobile bind -ldflags='-s -w' -target=ios -iosversion=11.0 -o \"out/mobileproxy.xcframework\" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy\n\n Drag the `out/mobileproxy.xcframework` bundle to the Xcode project. For\n more help see Go Mobile's [Building and deploying to\n iOS](https://go.dev/wiki/Mobile#building-and-deploying-to-ios-1).\n\nStep 2: Run the MobileProxy\n---------------------------\n\nInitialize and start the `MobileProxy` local proxy within your app's runtime.\nYou can use either a static transport configuration or the Smart Proxy for\ndynamic strategy selection.\n\n- **Static transport configuration** : Use the `RunProxy` function with a local\n address and transport configuration.\n\n ### Android\n\n import mobileproxy.*\n\n val dialer = StreamDialer(\"split:3\")\n\n // Use port zero to let the system pick an open port for you.\n val proxy = Mobileproxy.runProxy(\"localhost:0\", dialer)\n // Configure your networking library using proxy.host() and proxy.port() or proxy.address().\n // ...\n // Stop running the proxy.\n proxy.stop()\n\n ### iOS\n\n import Mobileproxy\n\n let dialer = MobileproxyStreamDialer(\"split:3\")\n\n // Use port zero to let the system pick an open port for you.\n let proxy = MobileproxyRunProxy(\"localhost:0\", dialer)\n // Configure your networking library using proxy.host() and proxy.port() or proxy.address().\n // ...\n // Stop running the proxy.\n proxy.stop()\n\n- **Smart Proxy** : The Smart Proxy dynamically selects DNS and TLS strategies\n based on specified test domains. You need to specify the configuration\n strategy in YAML format\n ([example](https://github.com/Jigsaw-Code/outline-sdk/blob/master/x/examples/smart-proxy/config.yaml)).\n\n ### Android\n\n val testDomains = Mobileproxy.newListFromLines(\"www.youtube.com\\ni.ytimg.com\")\n val strategiesConfig = \"...\" // Config YAML.\n val dialer = Mobileproxy.newSmartStreamDialer(testDomains, strategiesConfig, Mobileproxy.newStderrLogWriter())\n\n // Use port zero to let the system pick an open port for you.\n val proxy = Mobileproxy.runProxy(\"localhost:0\", dialer)\n // Configure your networking library using proxy.host() and proxy.port() or proxy.address().\n // ...\n // Stop running the proxy.\n proxy.stop()\n\n ### iOS\n\n import Mobileproxy\n\n var dialerError: NSError?\n let testDomains = MobileproxyNewListFromLines(\"www.youtube.com\\ni.ytimg.com\")\n let strategiesConfig = \"...\" // Config YAML.\n let dialer = MobileproxyNewSmartStreamDialer(\n testDomains,\n strategiesConfig,\n MobileproxyNewStderrLogWriter(),\n &dialerError\n )\n\n var proxyError: NSError?\n // Use port zero to let the system pick an open port for you.\n MobileproxyRunProxy(\"localhost:0\", dialer, &proxyError)\n // Configure your networking library using proxy.host() and proxy.port() or proxy.address().\n // ...\n // Stop running the proxy.\n proxy.stop()\n\nStep 3: Configure HTTP clients and networking libraries\n-------------------------------------------------------\n\nConfigure your networking libraries to use the local proxy address and port. \n\n### Dart/Flutter HttpClient\n\nSet the proxy with\n[`HttpClient.findProxy`](https://api.flutter.dev/flutter/dart-io/HttpClient/findProxy.html). \n\n HttpClient client = HttpClient();\n client.findProxy = (Uri uri) {\n return \"PROXY \" + proxy.address();\n };\n\n### OkHttp (Android)\n\nSet the proxy with\n[`OkHttpClient.Builder.proxy`](https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/-builder/proxy/). \n\n val proxyConfig = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxy.host(), proxy.port()))\n val client = OkHttpClient.Builder().proxy(proxyConfig).build()\n\n### JVM (Java, Kotlin)\n\nConfigure the proxy to use with [system\nproperties](https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html): \n\n System.setProperty(\"http.proxyHost\", proxy.host())\n System.setProperty(\"http.proxyPort\", String.valueOf(proxy.port()))\n System.setProperty(\"https.proxyHost\", proxy.host())\n System.setProperty(\"https.proxyPort\", String.valueOf(proxy.port()))\n\n### Android Web View\n\nApply a proxy configuration to all the web views in your application with\nthe\n[`androidx.webview`](https://developer.android.com/reference/androidx/webkit/ProxyController)\nlibrary: \n\n ProxyController.getInstance()\n .setProxyOverride(\n ProxyConfig.Builder()\n .addProxyRule(this.proxy!!.address())\n .build(),\n {}, // execution context for the following callback - do anything needed here once the proxy is applied, like refreshing web views\n {} // callback to be called once the ProxyConfig is applied\n )\n\n### iOS Web View\n\n\u003cbr /\u003e\n\nAs of iOS 17, you can add a proxy configuration to a `WKWebView` using its\n[`WKWebsiteDataStore`\nproperty](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration): \n\n let configuration = WKWebViewConfiguration()\n let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(proxyHost), port: NWEndpoint.Port(proxyPort)!)\n let proxyConfig = ProxyConfiguration.init(httpCONNECTProxy: endpoint)\n let websiteDataStore = WKWebsiteDataStore.default()\n websiteDataStore.proxyConfigurations = [proxyConfig]\n let webview = WKWebView(configuration: configuration)\n\nAdvanced: Generate a custom mobile library\n------------------------------------------\n\nFor advanced use cases, you can generate your own mobile libraries:\n\n1. **Create a Go library**: Develop a Go package wrapping the required SDK functionalities.\n2. **Generate mobile libraries** : Use `gomobile bind` to produce Android Archives (AAR) and Apple Frameworks. Examples:\n - [Outline Android Archive](https://github.com/Jigsaw-Code/outline-apps/blob/7058a89530a25a3de376a6ea2d4433a926787f50/client/go/Taskfile.yml#L67-L81)\n - [Outline Apple Framework](https://github.com/Jigsaw-Code/outline-apps/blob/7058a89530a25a3de376a6ea2d4433a926787f50/client/go/Taskfile.yml#L83-L95)\n3. **Integrate into your app**: Add the generated library to your mobile application.\n\n| **Note:** Use `gomobile bind` on your custom package, not directly on the SDK packages."]]