A new Flutter plugin based on my ClashKit and my Tun2Socks-Android
My ClashKit
forked from AppleClash/clash-apple, my Tun2Socks-Android
forked from universal-android-tun2socks
👍🏻Thanks @netyouli and Tun2SocksKit repo for iOS tun implementation.
dependencies:
clash_flt:
git:
url: https://github.com/LondonX/clash_flt.git
- Requires minSdkVersion 21
- Copy
ClashKit.aar
andtun2socks.aar
into<project-root>/android/app/
. - Add
implementation files("ClashKit.aar")
andimplementation files("tun2socks.aar")
in<project-root>/android/app/build.gradle
's dependencies section.
- Requires iOS 13 or newer. ≥15 is recommended because os iOS memory limitation of packet tunnel
- As
gomobile
stop supporting armv7a, you need to exclude this architecture in XCode.- Open
Runner.xcodeproj
, selectRunner
inPROJECT
list on the left. - In
Build Settings
->All
->Architectures
, set value toarm64
. - Add
ClashKit.xcframework
intoRunner
'sFrameworks and Libraries
an selectDo Not Embed
. - Add
Tun2SocksKit-main
bySwift Package Manager (SPM)
from https://github.com/EbrahimTahernejad/Tun2SocksKit or<project-root>/ios/Tun2SocksKit-main
. - Add
Tun2SocksKit
lib intoFrameworks and Libraries
ofPacketTunnel
target. - (Optional) Add
HevSocks5Tunnel.xcframework
- Open
- Modify
Runner.xcodeproj
- Open Runner's
Signing & Capabilities
tab. - You may need to enable
Network Extension
in Apple Developer Account page/Certificates, IDs & Profiles/Identifiers/YOUR_BUNDLE_ID/Edit/Network Extensions checkbox, before addNetwork Extension
and provision. - Add
Network Extension
andPersonal VPN
. - Check
App Proxy
andPacket Tunnel
ofNetwork Extension
.
- Open Runner's
- Add project Target of
Network-Extension
- Create a Target named
PacketTunnel
, the XCode will auto create a file namedPacketTunnelProvider.swift
. - Open
PacketTunnel
'sSigning & Capabilities
tab. - Add
Network Extension
andPersonal VPN
, just as step 3. - Modify
PacketTunnelProvider.swift
by paste from Example's PacketTunnelProvider.swfit
- Create a Target named
- Add app group
- Create a App Group named
group.<yourBundleId>
both inRunner
andPacketTunnel
Target.
- Create a App Group named
await ClashFlt.instance.init(clashHome);
final bool isDownloaded = await ClashFlt.instance.downloadProfile(clashProfileUrl, isForce: true);
final File? downloadedFile = await ClashFlt.instance.profileFile.value;
final bool isResolved = await ClashFlt.instance.resolveProfile();
final Profile? resolvedProfile = await ClashFlt.instance.profile.value;
final Profile? resolvedProfile = await ClashFlt.instance.profile.value;
final List<ProxyGroup>? groups = resolvedProfile?.proxyGroups;
final List<Proxy>? proxies = resolvedProfile?.proxies;
final List<String>? proxyNames = groups?.first.proxies;
// use ClashFlt.instance.findProxy to link proxy name with Proxy object.
final ProxyGroup group;//assigned in somewhere else
final Proxy proxy;//assigned in somewhere else
if (!ClashFlt.instance.isProxySelectable(group, proxy)) return;
if(ClashFlt.instance.isProxySelected(group, proxy)) return;
ClashFlt.instance.selectProxy(group, proxy) return
// start
final bool isStarted = await ClashFlt.instance.startClash();
// stop(no value return)
await ClashFlt.instance.stopClash();
profileFile
profileDownloading
countryDBFile
countryDBDownloading
profile
profileResolving
healthChecking
state.isRunning
queryTrafficNow
queryTrafficTotal
applyConfig
isClashRunning
startClash
stopClash