Last active
March 5, 2021 02:50
-
-
Save clydebarrow/efae37c762aa951c79e4f7fb090f17ee to your computer and use it in GitHub Desktop.
Check network reachability on iOS using RoboVM in Kotlin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.controlj.framework | |
import com.controlj.rx.DisposedEmitter | |
import io.reactivex.rxjava3.core.Observable | |
import io.reactivex.rxjava3.core.ObservableEmitter | |
import io.reactivex.rxjava3.schedulers.Schedulers | |
import org.robovm.apple.dispatch.DispatchQueue | |
import org.robovm.apple.foundation.NSOperatingSystemVersion | |
import org.robovm.apple.foundation.NSProcessInfo | |
import org.robovm.apple.network.NWPathMonitor | |
import org.robovm.apple.network.NWPathStatus | |
import java.net.InetAddress | |
import java.util.concurrent.TimeUnit | |
object NetworkStatus { | |
val iOS13 = NSOperatingSystemVersion(13, 0, 0) | |
val iOS12 = NSOperatingSystemVersion(12, 0, 0) | |
val iOS11 = NSOperatingSystemVersion(11, 0, 0) | |
val iOS10 = NSOperatingSystemVersion(10, 0, 0) | |
fun isOSVersionOrLater(version: NSOperatingSystemVersion): Boolean { | |
return NSProcessInfo.getSharedProcessInfo().isOperatingSystemAtLeastVersion(version) | |
} | |
val isIos13 = isOSVersionOrLater(iOS13) | |
val isIos12 = isOSVersionOrLater(iOS12) | |
val isIos11 = isOSVersionOrLater(iOS11) | |
val isIos10 = isOSVersionOrLater(iOS10) | |
val isSimulator: Boolean by lazy { | |
NSProcessInfo.getSharedProcessInfo().environment.containsKey("SIMULATOR_DEVICE_NAME") | |
} | |
const val NETWORK_INTERVAL = 60L // check network this often if required. | |
val NETWORK_TIME_UNIT = TimeUnit.SECONDS | |
const val NETWORK_TARGET = "google.com" | |
var networkEmitter: ObservableEmitter<Boolean> = DisposedEmitter() | |
private set | |
var networkReady = true | |
/** | |
* Listen for changes in network status. | |
*/ | |
val networkObserver = Observable.create<Boolean> { | |
networkEmitter = it | |
}.share() | |
init { | |
if (isIos12) { | |
try { | |
val monitor = NWPathMonitor() | |
monitor.setQueue(DispatchQueue.getMainQueue()) | |
monitor.setUpdateHandler { path -> | |
networkReady = path.status == NWPathStatus.satisfied | |
networkEmitter.onNext(networkReady) | |
} | |
monitor.start() | |
} catch (ex: Throwable) { | |
//logException(ex) | |
} | |
} | |
} | |
/** Check network availability for the given target. This will emit on initial call, every 60 seconds, | |
* or when there is a change in network status. It queries both the platform network monitor and does | |
* a DNS lookup to confirm actual reachability. | |
* | |
*/ | |
fun isNetworkAvailable(target: String = NETWORK_TARGET): Observable<Boolean> { | |
return Observable.merge( | |
networkObserver, Observable.interval( | |
0L, | |
NETWORK_INTERVAL, | |
NETWORK_TIME_UNIT, | |
Schedulers.io() | |
) | |
) | |
.map { | |
if (!networkReady) | |
false | |
else | |
try { | |
InetAddress.getByName(target) | |
true | |
} catch (ex: Exception) { | |
false | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment