expo-network 5.0.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/android/build.gradle +4 -4
- package/android/src/main/java/expo/modules/network/NetworkExceptions.kt +9 -0
- package/android/src/main/java/expo/modules/network/NetworkModule.kt +69 -79
- package/build/ExpoNetwork.d.ts +1 -1
- package/build/ExpoNetwork.d.ts.map +1 -1
- package/build/ExpoNetwork.js +2 -2
- package/build/ExpoNetwork.js.map +1 -1
- package/build/Network.types.d.ts +1 -1
- package/build/Network.types.d.ts.map +1 -1
- package/expo-module.config.json +10 -0
- package/ios/Exceptions.swift +7 -0
- package/ios/{EXNetwork.podspec → ExpoNetwork.podspec} +9 -3
- package/ios/NetworkModule.swift +102 -0
- package/ios/NetworkType.swift +28 -0
- package/package.json +2 -2
- package/src/ExpoNetwork.ts +2 -2
- package/android/src/main/java/expo/modules/network/NetworkPackage.kt +0 -11
- package/ios/EXNetwork/EXNetwork.h +0 -13
- package/ios/EXNetwork/EXNetwork.m +0 -123
- package/unimodule.json +0 -4
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 5.2.0 — 2023-02-03
|
|
14
|
+
|
|
15
|
+
### 💡 Others
|
|
16
|
+
|
|
17
|
+
- On Android bump `compileSdkVersion` and `targetSdkVersion` to `33`. ([#20721](https://github.com/expo/expo/pull/20721) by [@lukmccall](https://github.com/lukmccall))
|
|
18
|
+
|
|
19
|
+
## 5.1.0 — 2022-12-30
|
|
20
|
+
|
|
21
|
+
### 🎉 New features
|
|
22
|
+
|
|
23
|
+
- Migrated to Expo Modules API. ([#20083](https://github.com/expo/expo/pull/20083) and [#20303](https://github.com/expo/expo/pull/20303) by [@alanhughes](https://github.com/alanjhughes))
|
|
24
|
+
|
|
13
25
|
## 5.0.0 — 2022-10-25
|
|
14
26
|
|
|
15
27
|
### 🛠 Breaking changes
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ See [<ModuleName> docs](https://docs.expo.dev/versions/latest/sdk/<module-docs-n
|
|
|
6
6
|
|
|
7
7
|
# API documentation
|
|
8
8
|
|
|
9
|
-
- [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/network.
|
|
9
|
+
- [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/network.mdx)
|
|
10
10
|
- [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/network/)
|
|
11
11
|
|
|
12
12
|
# Installation in managed Expo projects
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '5.
|
|
6
|
+
version = '5.2.0'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -59,7 +59,7 @@ afterEvaluate {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
android {
|
|
62
|
-
compileSdkVersion safeExtGet("compileSdkVersion",
|
|
62
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 33)
|
|
63
63
|
|
|
64
64
|
compileOptions {
|
|
65
65
|
sourceCompatibility JavaVersion.VERSION_11
|
|
@@ -72,9 +72,9 @@ android {
|
|
|
72
72
|
|
|
73
73
|
defaultConfig {
|
|
74
74
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
75
|
-
targetSdkVersion safeExtGet("targetSdkVersion",
|
|
75
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
76
76
|
versionCode 11
|
|
77
|
-
versionName '5.
|
|
77
|
+
versionName '5.2.0'
|
|
78
78
|
}
|
|
79
79
|
lintOptions {
|
|
80
80
|
abortOnError false
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
package expo.modules.network
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.exception.CodedException
|
|
4
|
+
|
|
5
|
+
internal class NetworkAccessException(e: Exception) :
|
|
6
|
+
CodedException("Unable to access network information", e.cause)
|
|
7
|
+
|
|
8
|
+
internal class NetworkWifiException(e: Exception) :
|
|
9
|
+
CodedException("Wi-Fi information could not be acquired", e.cause)
|
|
@@ -1,31 +1,80 @@
|
|
|
1
1
|
package expo.modules.network
|
|
2
2
|
|
|
3
|
-
import expo.modules.core.Promise
|
|
4
|
-
import expo.modules.core.ExportedModule
|
|
5
|
-
import expo.modules.core.interfaces.ExpoMethod
|
|
6
|
-
import expo.modules.core.interfaces.RegistryLifecycleListener
|
|
7
|
-
|
|
8
|
-
import android.util.Log
|
|
9
|
-
import android.os.Build
|
|
10
|
-
import android.os.Bundle
|
|
11
3
|
import android.content.Context
|
|
4
|
+
import android.net.ConnectivityManager
|
|
5
|
+
import android.net.NetworkCapabilities
|
|
12
6
|
import android.net.NetworkInfo
|
|
13
7
|
import android.net.wifi.WifiInfo
|
|
14
8
|
import android.net.wifi.WifiManager
|
|
15
|
-
import android.
|
|
16
|
-
import android.
|
|
9
|
+
import android.os.Build
|
|
10
|
+
import android.os.Bundle
|
|
17
11
|
import android.provider.Settings
|
|
18
|
-
|
|
19
|
-
import
|
|
12
|
+
import android.util.Log
|
|
13
|
+
import expo.modules.kotlin.Promise
|
|
14
|
+
import expo.modules.kotlin.exception.Exceptions
|
|
15
|
+
import expo.modules.kotlin.modules.Module
|
|
16
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
20
17
|
import java.math.BigInteger
|
|
21
18
|
import java.net.InetAddress
|
|
22
19
|
import java.net.UnknownHostException
|
|
23
20
|
import java.nio.ByteOrder
|
|
24
21
|
|
|
25
|
-
private const val NAME = "ExpoNetwork"
|
|
26
22
|
private val TAG = NetworkModule::class.java.simpleName
|
|
27
23
|
|
|
28
|
-
class NetworkModule
|
|
24
|
+
class NetworkModule : Module() {
|
|
25
|
+
private val context: Context
|
|
26
|
+
get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
|
|
27
|
+
|
|
28
|
+
override fun definition() = ModuleDefinition {
|
|
29
|
+
Name("ExpoNetwork")
|
|
30
|
+
|
|
31
|
+
AsyncFunction("getNetworkStateAsync") { promise: Promise ->
|
|
32
|
+
val result = Bundle()
|
|
33
|
+
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
if (Build.VERSION.SDK_INT < 29) { // use getActiveNetworkInfo before api level 29
|
|
37
|
+
val netInfo = connectivityManager.activeNetworkInfo
|
|
38
|
+
val connectionType = getConnectionType(netInfo)
|
|
39
|
+
|
|
40
|
+
result.apply {
|
|
41
|
+
putBoolean("isInternetReachable", netInfo!!.isConnected)
|
|
42
|
+
putString("type", connectionType.value)
|
|
43
|
+
putBoolean("isConnected", connectionType.isDefined)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
promise.resolve(result)
|
|
47
|
+
} else {
|
|
48
|
+
val network = connectivityManager.activeNetwork
|
|
49
|
+
val isInternetReachable = network != null
|
|
50
|
+
|
|
51
|
+
val connectionType = if (isInternetReachable) {
|
|
52
|
+
val netCapabilities = connectivityManager.getNetworkCapabilities(network)
|
|
53
|
+
getConnectionType(netCapabilities)
|
|
54
|
+
} else {
|
|
55
|
+
null
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
result.apply {
|
|
59
|
+
putString("type", connectionType?.value ?: NetworkStateType.NONE.value)
|
|
60
|
+
putBoolean("isInternetReachable", isInternetReachable)
|
|
61
|
+
putBoolean("isConnected", connectionType != null && connectionType.isDefined)
|
|
62
|
+
}
|
|
63
|
+
promise.resolve(result)
|
|
64
|
+
}
|
|
65
|
+
} catch (e: Exception) {
|
|
66
|
+
throw NetworkAccessException(e)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
AsyncFunction("getIpAddressAsync") {
|
|
71
|
+
return@AsyncFunction rawIpToString(wifiInfo.ipAddress)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
AsyncFunction("isAirplaneModeEnabledAsync") {
|
|
75
|
+
return@AsyncFunction Settings.Global.getInt(context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
|
|
76
|
+
}
|
|
77
|
+
}
|
|
29
78
|
|
|
30
79
|
enum class NetworkStateType(val value: String) {
|
|
31
80
|
NONE("NONE"),
|
|
@@ -42,15 +91,13 @@ class NetworkModule(private val appContext: Context) : ExportedModule(appContext
|
|
|
42
91
|
get() = this.value != "NONE" && this.value != "UNKNOWN"
|
|
43
92
|
}
|
|
44
93
|
|
|
45
|
-
override fun getName() = NAME
|
|
46
|
-
|
|
47
94
|
private val wifiInfo: WifiInfo
|
|
48
95
|
get() = try {
|
|
49
|
-
val manager =
|
|
96
|
+
val manager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
|
50
97
|
manager.connectionInfo
|
|
51
98
|
} catch (e: Exception) {
|
|
52
99
|
Log.e(TAG, e.message ?: "Wi-Fi information could not be acquired")
|
|
53
|
-
throw e
|
|
100
|
+
throw NetworkWifiException(e)
|
|
54
101
|
}
|
|
55
102
|
|
|
56
103
|
private fun getConnectionType(netInfo: NetworkInfo?): NetworkStateType = when (netInfo?.type) {
|
|
@@ -75,12 +122,12 @@ class NetworkModule(private val appContext: Context) : ExportedModule(appContext
|
|
|
75
122
|
else -> NetworkStateType.UNKNOWN
|
|
76
123
|
}
|
|
77
124
|
|
|
78
|
-
private fun rawIpToString(
|
|
125
|
+
private fun rawIpToString(ipAddress: Int): String {
|
|
79
126
|
// Convert little-endian to big-endian if needed
|
|
80
127
|
val ip = if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
|
|
81
|
-
Integer.reverseBytes(
|
|
128
|
+
Integer.reverseBytes(ipAddress)
|
|
82
129
|
} else {
|
|
83
|
-
|
|
130
|
+
ipAddress
|
|
84
131
|
}
|
|
85
132
|
|
|
86
133
|
var ipByteArray = BigInteger.valueOf(ip.toLong()).toByteArray()
|
|
@@ -89,66 +136,9 @@ class NetworkModule(private val appContext: Context) : ExportedModule(appContext
|
|
|
89
136
|
}
|
|
90
137
|
|
|
91
138
|
return try {
|
|
92
|
-
InetAddress.getByAddress(ipByteArray).hostAddress
|
|
139
|
+
InetAddress.getByAddress(ipByteArray).hostAddress as String
|
|
93
140
|
} catch (e: UnknownHostException) {
|
|
94
141
|
"0.0.0.0"
|
|
95
142
|
}
|
|
96
143
|
}
|
|
97
|
-
|
|
98
|
-
@ExpoMethod
|
|
99
|
-
fun getNetworkStateAsync(promise: Promise) {
|
|
100
|
-
val result = Bundle()
|
|
101
|
-
val connectivityManager = appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
if (Build.VERSION.SDK_INT < 29) { // use getActiveNetworkInfo before api level 29
|
|
105
|
-
val netInfo = connectivityManager.activeNetworkInfo
|
|
106
|
-
val connectionType = getConnectionType(netInfo)
|
|
107
|
-
|
|
108
|
-
result.apply {
|
|
109
|
-
putBoolean("isInternetReachable", netInfo!!.isConnected)
|
|
110
|
-
putString("type", connectionType.value)
|
|
111
|
-
putBoolean("isConnected", connectionType.isDefined)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
promise.resolve(result)
|
|
115
|
-
} else {
|
|
116
|
-
val network = connectivityManager.activeNetwork
|
|
117
|
-
val isInternetReachable = network != null
|
|
118
|
-
|
|
119
|
-
val connectionType = if (isInternetReachable) {
|
|
120
|
-
val netCapabilities = connectivityManager.getNetworkCapabilities(network)
|
|
121
|
-
getConnectionType(netCapabilities)
|
|
122
|
-
} else {
|
|
123
|
-
null
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
result.apply {
|
|
127
|
-
putString("type", connectionType?.value ?: NetworkStateType.NONE.value)
|
|
128
|
-
putBoolean("isInternetReachable", isInternetReachable)
|
|
129
|
-
putBoolean("isConnected", connectionType != null && connectionType.isDefined)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
promise.resolve(result)
|
|
133
|
-
}
|
|
134
|
-
} catch (e: Exception) {
|
|
135
|
-
promise.reject("ERR_NETWORK_NO_ACCESS_NETWORKINFO", "Unable to access network information", e)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
@ExpoMethod
|
|
140
|
-
fun getIpAddressAsync(promise: Promise) {
|
|
141
|
-
try {
|
|
142
|
-
promise.resolve(rawIpToString(wifiInfo.ipAddress))
|
|
143
|
-
} catch (e: Exception) {
|
|
144
|
-
Log.e(TAG, e.message ?: "Could not get IP address")
|
|
145
|
-
promise.reject("ERR_NETWORK_IP_ADDRESS", "Unknown Host Exception", e)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
@ExpoMethod
|
|
150
|
-
fun isAirplaneModeEnabledAsync(promise: Promise) {
|
|
151
|
-
val isAirplaneMode = Settings.Global.getInt(appContext.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
|
|
152
|
-
promise.resolve(isAirplaneMode)
|
|
153
|
-
}
|
|
154
144
|
}
|
package/build/ExpoNetwork.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoNetwork.d.ts","sourceRoot":"","sources":["../src/ExpoNetwork.ts"],"names":[],"mappings":";AACA,
|
|
1
|
+
{"version":3,"file":"ExpoNetwork.d.ts","sourceRoot":"","sources":["../src/ExpoNetwork.ts"],"names":[],"mappings":";AACA,wBAAkD"}
|
package/build/ExpoNetwork.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default
|
|
1
|
+
import { requireNativeModule } from 'expo-modules-core';
|
|
2
|
+
export default requireNativeModule('ExpoNetwork');
|
|
3
3
|
//# sourceMappingURL=ExpoNetwork.js.map
|
package/build/ExpoNetwork.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoNetwork.js","sourceRoot":"","sources":["../src/ExpoNetwork.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ExpoNetwork.js","sourceRoot":"","sources":["../src/ExpoNetwork.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,eAAe,mBAAmB,CAAC,aAAa,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\nexport default requireNativeModule('ExpoNetwork');\n"]}
|
package/build/Network.types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Network.types.d.ts","sourceRoot":"","sources":["../src/Network.types.ts"],"names":[],"mappings":"AACA,
|
|
1
|
+
{"version":3,"file":"Network.types.d.ts","sourceRoot":"","sources":["../src/Network.types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAGF;;GAEG;AACH,oBAAY,gBAAgB;IAC1B;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,OAAO,YAAY;IACnB;;;OAGG;IACH,QAAQ,aAAa;IACrB;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,SAAS,cAAc;IACvB;;OAEG;IACH,QAAQ,aAAa;IACrB;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,GAAG,QAAQ;IACX;;OAEG;IACH,KAAK,UAAU;CAChB"}
|
|
@@ -3,7 +3,7 @@ require 'json'
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
|
4
4
|
|
|
5
5
|
Pod::Spec.new do |s|
|
|
6
|
-
s.name = '
|
|
6
|
+
s.name = 'ExpoNetwork'
|
|
7
7
|
s.version = package['version']
|
|
8
8
|
s.summary = package['description']
|
|
9
9
|
s.description = package['description']
|
|
@@ -15,11 +15,17 @@ Pod::Spec.new do |s|
|
|
|
15
15
|
s.static_framework = true
|
|
16
16
|
|
|
17
17
|
s.dependency 'ExpoModulesCore'
|
|
18
|
+
|
|
19
|
+
# Swift/Objective-C compatibility
|
|
20
|
+
s.pod_target_xcconfig = {
|
|
21
|
+
'DEFINES_MODULE' => 'YES',
|
|
22
|
+
'SWIFT_COMPILATION_MODE' => 'wholemodule'
|
|
23
|
+
}
|
|
18
24
|
|
|
19
25
|
if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
|
|
20
|
-
s.source_files = "
|
|
26
|
+
s.source_files = "**/*.h"
|
|
21
27
|
s.vendored_frameworks = "#{s.name}.xcframework"
|
|
22
28
|
else
|
|
23
|
-
s.source_files = "
|
|
29
|
+
s.source_files = "**/*.{h,m,swift}"
|
|
24
30
|
end
|
|
25
31
|
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import SystemConfiguration
|
|
3
|
+
import Network
|
|
4
|
+
|
|
5
|
+
public final class NetworkModule: Module {
|
|
6
|
+
private let monitor = NWPathMonitor()
|
|
7
|
+
private let monitorQueue = DispatchQueue.global(qos: .default)
|
|
8
|
+
|
|
9
|
+
public func definition() -> ModuleDefinition {
|
|
10
|
+
Name("ExpoNetwork")
|
|
11
|
+
|
|
12
|
+
OnCreate {
|
|
13
|
+
monitor.start(queue: monitorQueue)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
AsyncFunction("getIpAddressAsync") { () -> String? in
|
|
17
|
+
return try getIPAddress()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
AsyncFunction("getNetworkStateAsync") {
|
|
21
|
+
return getNetworkStateAsync()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
OnDestroy {
|
|
25
|
+
monitor.cancel()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private func getIPAddress() throws -> String {
|
|
30
|
+
var address = "0.0.0.0"
|
|
31
|
+
var ifaddr: UnsafeMutablePointer<ifaddrs>?
|
|
32
|
+
|
|
33
|
+
let error = getifaddrs(&ifaddr)
|
|
34
|
+
|
|
35
|
+
guard error == 0 else {
|
|
36
|
+
throw IpAddressException(error)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
guard let firstAddr = ifaddr else {
|
|
40
|
+
return address
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
|
|
44
|
+
let temp = ifptr.pointee
|
|
45
|
+
let family = temp.ifa_addr.pointee.sa_family
|
|
46
|
+
|
|
47
|
+
if family == UInt8(AF_INET) {
|
|
48
|
+
let name = String(cString: temp.ifa_name)
|
|
49
|
+
if name == "en0" || name == "en1" {
|
|
50
|
+
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
|
|
51
|
+
getnameinfo(
|
|
52
|
+
temp.ifa_addr,
|
|
53
|
+
socklen_t(temp.ifa_addr.pointee.sa_len),
|
|
54
|
+
&hostname,
|
|
55
|
+
socklen_t(hostname.count),
|
|
56
|
+
nil,
|
|
57
|
+
socklen_t(0),
|
|
58
|
+
NI_NUMERICHOST)
|
|
59
|
+
address = String(cString: hostname)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
freeifaddrs(ifaddr)
|
|
65
|
+
return address
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private func getNetworkStateAsync() -> [String: Any] {
|
|
69
|
+
let path = monitor.currentPath
|
|
70
|
+
let isConnected = path.status == .satisfied
|
|
71
|
+
var currentNetworkType = NetworkType.unknown
|
|
72
|
+
|
|
73
|
+
if !isConnected {
|
|
74
|
+
return [
|
|
75
|
+
"type": NetworkType.none.description,
|
|
76
|
+
"isConnected": isConnected,
|
|
77
|
+
"isInternetReachable": isConnected
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let connectionType = NWInterface
|
|
82
|
+
.InterfaceType
|
|
83
|
+
.allCases
|
|
84
|
+
.filter { path.usesInterfaceType($0) }
|
|
85
|
+
.first
|
|
86
|
+
|
|
87
|
+
switch connectionType {
|
|
88
|
+
case .wifi:
|
|
89
|
+
currentNetworkType = .wifi
|
|
90
|
+
case .cellular:
|
|
91
|
+
currentNetworkType = .cellular
|
|
92
|
+
default:
|
|
93
|
+
currentNetworkType = .unknown
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return [
|
|
97
|
+
"type": currentNetworkType.description,
|
|
98
|
+
"isConnected": isConnected,
|
|
99
|
+
"isInternetReachable": isConnected
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Network
|
|
2
|
+
|
|
3
|
+
extension NWInterface.InterfaceType: CaseIterable {
|
|
4
|
+
public static var allCases: [NWInterface.InterfaceType] = [
|
|
5
|
+
.other,
|
|
6
|
+
.wifi,
|
|
7
|
+
.cellular,
|
|
8
|
+
.loopback,
|
|
9
|
+
.wiredEthernet
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
enum NetworkType: CustomStringConvertible {
|
|
14
|
+
case unknown, wifi, none, cellular
|
|
15
|
+
|
|
16
|
+
var description: String {
|
|
17
|
+
switch self {
|
|
18
|
+
case .wifi:
|
|
19
|
+
return "WIFI"
|
|
20
|
+
case .cellular:
|
|
21
|
+
return "CELLULAR"
|
|
22
|
+
case .unknown:
|
|
23
|
+
return "UNKNOWN"
|
|
24
|
+
case .none:
|
|
25
|
+
return "NONE"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-network",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Provides useful information about the device's network such as its IP address, MAC address, and airplane mode status",
|
|
5
5
|
"main": "build/Network.js",
|
|
6
6
|
"types": "build/Network.d.ts",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"expo": "*"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "1815e2eaad8c753588c7b1eb74420174a28e01f4"
|
|
40
40
|
}
|
package/src/ExpoNetwork.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default
|
|
1
|
+
import { requireNativeModule } from 'expo-modules-core';
|
|
2
|
+
export default requireNativeModule('ExpoNetwork');
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
package expo.modules.network
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
|
|
5
|
-
import expo.modules.core.BasePackage
|
|
6
|
-
import expo.modules.core.ExportedModule
|
|
7
|
-
|
|
8
|
-
class NetworkPackage : BasePackage() {
|
|
9
|
-
override fun createExportedModules(context: Context): List<ExportedModule> =
|
|
10
|
-
listOf(NetworkModule(context))
|
|
11
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// Copyright © 2018 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <ExpoModulesCore/EXExportedModule.h>
|
|
4
|
-
#import <ExpoModulesCore/EXModuleRegistryConsumer.h>
|
|
5
|
-
|
|
6
|
-
static NSString *const EXNetworkTypeUnknown = @"UNKNOWN";
|
|
7
|
-
static NSString *const EXNetworkTypeNone = @"NONE";
|
|
8
|
-
static NSString *const EXNetworkTypeWifi = @"WIFI";
|
|
9
|
-
static NSString *const EXNetworkTypeCellular = @"CELLULAR";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@interface EXNetwork : EXExportedModule <EXModuleRegistryConsumer>
|
|
13
|
-
@end
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
#import <EXNetwork/EXNetwork.h>
|
|
4
|
-
#import <SystemConfiguration/SystemConfiguration.h>
|
|
5
|
-
|
|
6
|
-
#import <ifaddrs.h>
|
|
7
|
-
#import <errno.h>
|
|
8
|
-
#import <arpa/inet.h>
|
|
9
|
-
|
|
10
|
-
@interface EXNetwork ()
|
|
11
|
-
|
|
12
|
-
@property (nonatomic, weak) EXModuleRegistry *moduleRegistry;
|
|
13
|
-
@property (nonatomic) SCNetworkReachabilityRef reachabilityRef;
|
|
14
|
-
@property (nonatomic) SCNetworkReachabilityFlags lastFlags;
|
|
15
|
-
@property (nonatomic) NSString *type;
|
|
16
|
-
|
|
17
|
-
@end
|
|
18
|
-
|
|
19
|
-
@implementation EXNetwork
|
|
20
|
-
|
|
21
|
-
// Creates a new "blank" state
|
|
22
|
-
- (instancetype)init
|
|
23
|
-
{
|
|
24
|
-
self = [super init];
|
|
25
|
-
if (self) {
|
|
26
|
-
_type = EXNetworkTypeUnknown;
|
|
27
|
-
}
|
|
28
|
-
return self;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
EX_EXPORT_MODULE(ExpoNetwork);
|
|
32
|
-
|
|
33
|
-
- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry
|
|
34
|
-
{
|
|
35
|
-
_moduleRegistry = moduleRegistry;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
EX_EXPORT_METHOD_AS(getIpAddressAsync,
|
|
39
|
-
getIpAddressAsyncWithResolver:(EXPromiseResolveBlock)resolve rejecter:(EXPromiseRejectBlock)reject)
|
|
40
|
-
{
|
|
41
|
-
NSString *address = @"0.0.0.0";
|
|
42
|
-
struct ifaddrs *interfaces = NULL;
|
|
43
|
-
struct ifaddrs *temp_addr = NULL;
|
|
44
|
-
int error = 0;
|
|
45
|
-
// retrieve the current interfaces - On success, returns 0; on error, -1 is returned, and errno is set appropriately.
|
|
46
|
-
error = getifaddrs(&interfaces);
|
|
47
|
-
|
|
48
|
-
if (error == 0) {
|
|
49
|
-
// Loop through linked list of interfaces
|
|
50
|
-
temp_addr = interfaces;
|
|
51
|
-
while(temp_addr != NULL) {
|
|
52
|
-
if(temp_addr->ifa_addr->sa_family == AF_INET) {
|
|
53
|
-
// Check if interface is en0 which is the wifi connection on the iPhone
|
|
54
|
-
if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
|
|
55
|
-
// Get NSString from C String
|
|
56
|
-
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
temp_addr = temp_addr->ifa_next;
|
|
60
|
-
}
|
|
61
|
-
resolve(address);
|
|
62
|
-
} else {
|
|
63
|
-
NSString *errorMessage = [NSString stringWithFormat:@"%@/%d/%s", @"No network interfaces could be retrieved. getifaddrs() failed with error number: ", errno, strerror(errno)];
|
|
64
|
-
|
|
65
|
-
reject(@"ERR_NETWORK_IP_ADDRESS", errorMessage, nil);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Free memory
|
|
69
|
-
freeifaddrs(interfaces);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
EX_EXPORT_METHOD_AS(getNetworkStateAsync,
|
|
73
|
-
getNetworkStateAsyncWithResolver:(EXPromiseResolveBlock)resolve
|
|
74
|
-
rejecter:(EXPromiseRejectBlock)reject)
|
|
75
|
-
{
|
|
76
|
-
_reachabilityRef = [self createReachabilityRef];
|
|
77
|
-
SCNetworkReachabilityFlags flags = [self lastFlags];
|
|
78
|
-
|
|
79
|
-
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0 ||
|
|
80
|
-
(flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0) {
|
|
81
|
-
_type = EXNetworkTypeNone;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
#if !TARGET_OS_TV
|
|
85
|
-
else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
|
|
86
|
-
_type = EXNetworkTypeCellular;
|
|
87
|
-
}
|
|
88
|
-
#endif
|
|
89
|
-
else {
|
|
90
|
-
_type = EXNetworkTypeWifi;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
resolve(@{
|
|
94
|
-
@"type": [self type],
|
|
95
|
-
@"isConnected": @([self connected]),
|
|
96
|
-
@"isInternetReachable": @([self connected])
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
- (SCNetworkReachabilityRef)createReachabilityRef
|
|
102
|
-
{
|
|
103
|
-
struct sockaddr_in zeroAddress;
|
|
104
|
-
bzero(&zeroAddress, sizeof(zeroAddress));
|
|
105
|
-
zeroAddress.sin_len = sizeof(zeroAddress);
|
|
106
|
-
zeroAddress.sin_family = AF_INET;
|
|
107
|
-
|
|
108
|
-
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *) &zeroAddress);
|
|
109
|
-
|
|
110
|
-
// Set the state the first time
|
|
111
|
-
SCNetworkReachabilityFlags flags;
|
|
112
|
-
SCNetworkReachabilityGetFlags(reachability, &flags);
|
|
113
|
-
_lastFlags = flags;
|
|
114
|
-
|
|
115
|
-
return reachability;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
- (BOOL)connected
|
|
119
|
-
{
|
|
120
|
-
return ![self.type isEqualToString:EXNetworkTypeUnknown] && ![self.type isEqualToString:EXNetworkTypeNone];
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
@end
|
package/unimodule.json
DELETED