react-native-kookit 0.2.7 → 0.2.9
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/ANDROID_BUILD_FIX.md +117 -0
- package/SMB_COMPLETE_GUIDE.md +308 -0
- package/SMB_IMPLEMENTATION_SUMMARY.md +229 -0
- package/SMB_USAGE.md +275 -0
- package/android/build.gradle +7 -0
- package/android/src/main/java/expo/modules/kookit/ReactNativeKookitModule.kt +224 -1
- package/android/src/main/java/expo/modules/kookit/SmbClient.kt +198 -0
- package/build/ReactNativeKookit.types.d.ts +39 -0
- package/build/ReactNativeKookit.types.d.ts.map +1 -1
- package/build/ReactNativeKookit.types.js.map +1 -1
- package/build/ReactNativeKookitModule.d.ts +23 -1
- package/build/ReactNativeKookitModule.d.ts.map +1 -1
- package/build/ReactNativeKookitModule.js.map +1 -1
- package/build/SmbClient.d.ts +45 -0
- package/build/SmbClient.d.ts.map +1 -0
- package/build/SmbClient.js +122 -0
- package/build/SmbClient.js.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/ios/ReactNativeKookit.podspec +1 -0
- package/ios/ReactNativeKookitModule.swift +407 -2
- package/ios/SMBClient.podspec +18 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import MediaPlayer
|
|
|
4
4
|
import AVFoundation
|
|
5
5
|
import Foundation
|
|
6
6
|
import Network
|
|
7
|
+
import SMBClient
|
|
7
8
|
|
|
8
9
|
// MARK: - FTP Related Types and Classes
|
|
9
10
|
|
|
@@ -803,7 +804,171 @@ class FtpClient: @unchecked Sendable {
|
|
|
803
804
|
}
|
|
804
805
|
}
|
|
805
806
|
|
|
806
|
-
// MARK: -
|
|
807
|
+
// MARK: - SMB Client with SMBClient library
|
|
808
|
+
|
|
809
|
+
struct SmbFileInfo {
|
|
810
|
+
let name: String
|
|
811
|
+
let isDirectory: Bool
|
|
812
|
+
let size: Int64
|
|
813
|
+
let lastModified: String
|
|
814
|
+
let attributes: String?
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
class SmbClient: @unchecked Sendable {
|
|
818
|
+
private var client: SMBClient?
|
|
819
|
+
private(set) var isConnected: Bool = false
|
|
820
|
+
private var currentShare: String?
|
|
821
|
+
private weak var progressDelegate: SmbProgressDelegate?
|
|
822
|
+
|
|
823
|
+
func connect(host: String, username: String, password: String, domain: String? = nil, share: String? = nil, timeout: TimeInterval = 10.0) async throws {
|
|
824
|
+
client = SMBClient(host: host)
|
|
825
|
+
|
|
826
|
+
try await client!.login(username: username, password: password)
|
|
827
|
+
isConnected = true
|
|
828
|
+
|
|
829
|
+
if let share = share {
|
|
830
|
+
try await client!.connectShare(share)
|
|
831
|
+
currentShare = share
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
func connectShare(_ shareName: String) async throws {
|
|
836
|
+
guard let client = client, isConnected else {
|
|
837
|
+
throw FtpError.notConnected
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if currentShare != nil {
|
|
841
|
+
try await client.disconnectShare()
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
try await client.connectShare(shareName)
|
|
845
|
+
currentShare = shareName
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
func listFiles(path: String? = nil) async throws -> [SmbFileInfo] {
|
|
849
|
+
guard let client = client, isConnected else {
|
|
850
|
+
throw FtpError.notConnected
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
guard currentShare != nil else {
|
|
854
|
+
throw FtpError.commandFailed("No share connected. Connect to a share first.")
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
let directoryPath = path?.isEmpty == false ? path! : ""
|
|
858
|
+
let files = try await client.listDirectory(path: directoryPath)
|
|
859
|
+
|
|
860
|
+
return files.map { file in
|
|
861
|
+
SmbFileInfo(
|
|
862
|
+
name: file.name,
|
|
863
|
+
isDirectory: file.isDirectory,
|
|
864
|
+
size: Int64(file.size),
|
|
865
|
+
lastModified: formatDate(file.lastWriteTime),
|
|
866
|
+
attributes: nil
|
|
867
|
+
)
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
func downloadFile(remotePath: String, localPath: String) async throws {
|
|
872
|
+
guard let client = client, isConnected else {
|
|
873
|
+
throw FtpError.notConnected
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
guard currentShare != nil else {
|
|
877
|
+
throw FtpError.commandFailed("No share connected. Connect to a share first.")
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
let localURL = URL(fileURLWithPath: localPath)
|
|
881
|
+
try FileManager.default.createDirectory(at: localURL.deletingLastPathComponent(),
|
|
882
|
+
withIntermediateDirectories: true,
|
|
883
|
+
attributes: nil)
|
|
884
|
+
|
|
885
|
+
let data = try await client.download(path: remotePath)
|
|
886
|
+
try data.write(to: localURL)
|
|
887
|
+
|
|
888
|
+
progressDelegate?.onComplete()
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
func uploadFile(localPath: String, remotePath: String) async throws {
|
|
892
|
+
guard let client = client, isConnected else {
|
|
893
|
+
throw FtpError.notConnected
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
guard currentShare != nil else {
|
|
897
|
+
throw FtpError.commandFailed("No share connected. Connect to a share first.")
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
let localURL = URL(fileURLWithPath: localPath)
|
|
901
|
+
guard FileManager.default.fileExists(atPath: localPath) else {
|
|
902
|
+
throw FtpError.fileNotFound("Local file not found: \(localPath)")
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
let data = try Data(contentsOf: localURL)
|
|
906
|
+
try await client.upload(content: data, path: remotePath)
|
|
907
|
+
|
|
908
|
+
progressDelegate?.onComplete()
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
func deleteFile(remotePath: String, isDirectory: Bool = false) async throws {
|
|
912
|
+
guard let client = client, isConnected else {
|
|
913
|
+
throw FtpError.notConnected
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
guard currentShare != nil else {
|
|
917
|
+
throw FtpError.commandFailed("No share connected. Connect to a share first.")
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
if isDirectory {
|
|
921
|
+
try await client.deleteDirectory(path: remotePath)
|
|
922
|
+
} else {
|
|
923
|
+
try await client.deleteFile(path: remotePath)
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
func createDirectory(remotePath: String) async throws {
|
|
928
|
+
guard let client = client, isConnected else {
|
|
929
|
+
throw FtpError.notConnected
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
guard currentShare != nil else {
|
|
933
|
+
throw FtpError.commandFailed("No share connected. Connect to a share first.")
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
try await client.createDirectory(path: remotePath)
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
func disconnect() async {
|
|
940
|
+
guard let client = client else { return }
|
|
941
|
+
|
|
942
|
+
do {
|
|
943
|
+
if currentShare != nil {
|
|
944
|
+
try await client.disconnectShare()
|
|
945
|
+
}
|
|
946
|
+
try await client.logoff()
|
|
947
|
+
} catch {
|
|
948
|
+
// Ignore errors during disconnect
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
self.client = nil
|
|
952
|
+
isConnected = false
|
|
953
|
+
currentShare = nil
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
func setProgressDelegate(_ delegate: SmbProgressDelegate?) {
|
|
957
|
+
self.progressDelegate = delegate
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
private func formatDate(_ date: Date) -> String {
|
|
961
|
+
let formatter = DateFormatter()
|
|
962
|
+
formatter.dateFormat = "MMM dd HH:mm"
|
|
963
|
+
return formatter.string(from: date)
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
protocol SmbProgressDelegate: AnyObject {
|
|
968
|
+
func onProgress(transferred: Int64, total: Int64)
|
|
969
|
+
func onComplete()
|
|
970
|
+
func onError(error: String)
|
|
971
|
+
}// MARK: - Main Module
|
|
807
972
|
|
|
808
973
|
public class ReactNativeKookitModule: Module {
|
|
809
974
|
private var volumeView: MPVolumeView?
|
|
@@ -811,6 +976,7 @@ public class ReactNativeKookitModule: Module {
|
|
|
811
976
|
private var isVolumeKeyInterceptionEnabled = false
|
|
812
977
|
private var previousVolume: Float = 0.0
|
|
813
978
|
private var ftpClients: [String: FtpClient] = [:] // Store multiple FTP clients by ID
|
|
979
|
+
private var smbClients: [String: SmbClient] = [:] // Store multiple SMB clients by ID
|
|
814
980
|
|
|
815
981
|
// Each module class must implement the definition function. The definition consists of components
|
|
816
982
|
// that describes the module's functionality and behavior.
|
|
@@ -827,7 +993,9 @@ public class ReactNativeKookitModule: Module {
|
|
|
827
993
|
])
|
|
828
994
|
|
|
829
995
|
// Defines event names that the module can send to JavaScript.
|
|
830
|
-
|
|
996
|
+
Events("onChange", "onVolumeButtonPressed",
|
|
997
|
+
"onFtpProgress", "onFtpComplete", "onFtpError",
|
|
998
|
+
"onSmbProgress", "onSmbComplete", "onSmbError")
|
|
831
999
|
|
|
832
1000
|
// Defines a JavaScript synchronous function that runs the native code on the JavaScript thread.
|
|
833
1001
|
Function("hello") {
|
|
@@ -1116,6 +1284,209 @@ public class ReactNativeKookitModule: Module {
|
|
|
1116
1284
|
])
|
|
1117
1285
|
}
|
|
1118
1286
|
|
|
1287
|
+
// MARK: - SMB Client API
|
|
1288
|
+
|
|
1289
|
+
AsyncFunction("createSmbClient") { (clientId: String, promise: Promise) in
|
|
1290
|
+
if self.smbClients[clientId] != nil {
|
|
1291
|
+
promise.reject("SMB_CLIENT_EXISTS", "SMB client with ID '\(clientId)' already exists")
|
|
1292
|
+
return
|
|
1293
|
+
}
|
|
1294
|
+
self.smbClients[clientId] = SmbClient()
|
|
1295
|
+
promise.resolve(["clientId": clientId])
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
AsyncFunction("disposeSmbClient") { (clientId: String, promise: Promise) in
|
|
1299
|
+
if let client = self.smbClients[clientId] {
|
|
1300
|
+
Task {
|
|
1301
|
+
await client.disconnect()
|
|
1302
|
+
self.smbClients.removeValue(forKey: clientId)
|
|
1303
|
+
promise.resolve([:])
|
|
1304
|
+
}
|
|
1305
|
+
} else {
|
|
1306
|
+
promise.resolve([:])
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
AsyncFunction("getSmbClientStatus") { (clientId: String, promise: Promise) in
|
|
1311
|
+
guard let client = self.smbClients[clientId] else {
|
|
1312
|
+
promise.resolve(["exists": false, "connected": false])
|
|
1313
|
+
return
|
|
1314
|
+
}
|
|
1315
|
+
promise.resolve(["exists": true, "connected": client.isConnected])
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
AsyncFunction("listSmbClients") { (promise: Promise) in
|
|
1319
|
+
let clientsInfo = self.smbClients.mapValues { client in
|
|
1320
|
+
["connected": client.isConnected]
|
|
1321
|
+
}
|
|
1322
|
+
promise.resolve(["clients": clientsInfo, "count": self.smbClients.count])
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
AsyncFunction("smbClientConnect") { (clientId: String, config: [String: Any], promise: Promise) in
|
|
1326
|
+
guard let client = self.smbClients[clientId] else {
|
|
1327
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1328
|
+
return
|
|
1329
|
+
}
|
|
1330
|
+
let host = config["host"] as? String ?? ""
|
|
1331
|
+
let username = config["username"] as? String ?? ""
|
|
1332
|
+
let password = config["password"] as? String ?? ""
|
|
1333
|
+
let domain = config["domain"] as? String
|
|
1334
|
+
let share = config["share"] as? String
|
|
1335
|
+
let timeout = (config["timeout"] as? TimeInterval) ?? 10.0
|
|
1336
|
+
if host.isEmpty || username.isEmpty {
|
|
1337
|
+
promise.reject("SMB_INVALID_CONFIG", "Missing host or username")
|
|
1338
|
+
return
|
|
1339
|
+
}
|
|
1340
|
+
Task {
|
|
1341
|
+
do {
|
|
1342
|
+
try await client.connect(host: host, username: username, password: password, domain: domain, share: share, timeout: timeout)
|
|
1343
|
+
promise.resolve(["clientId": clientId, "connected": true])
|
|
1344
|
+
} catch {
|
|
1345
|
+
promise.reject("SMB_CONNECT_ERROR", error.localizedDescription)
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
AsyncFunction("smbClientDisconnect") { (clientId: String, promise: Promise) in
|
|
1351
|
+
guard let client = self.smbClients[clientId] else {
|
|
1352
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1353
|
+
return
|
|
1354
|
+
}
|
|
1355
|
+
Task {
|
|
1356
|
+
await client.disconnect()
|
|
1357
|
+
promise.resolve(["clientId": clientId, "disconnected": true])
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
AsyncFunction("smbClientConnectShare") { (clientId: String, shareName: String, promise: Promise) in
|
|
1362
|
+
guard let client = self.smbClients[clientId] else {
|
|
1363
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1364
|
+
return
|
|
1365
|
+
}
|
|
1366
|
+
Task {
|
|
1367
|
+
do {
|
|
1368
|
+
try await client.connectShare(shareName)
|
|
1369
|
+
promise.resolve(["clientId": clientId, "share": shareName, "connected": true])
|
|
1370
|
+
} catch {
|
|
1371
|
+
promise.reject("SMB_CONNECT_SHARE_ERROR", error.localizedDescription)
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
AsyncFunction("smbClientList") { (clientId: String, path: String?, promise: Promise) in
|
|
1377
|
+
guard let client = self.smbClients[clientId] else {
|
|
1378
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1379
|
+
return
|
|
1380
|
+
}
|
|
1381
|
+
Task {
|
|
1382
|
+
do {
|
|
1383
|
+
let files = try await client.listFiles(path: path)
|
|
1384
|
+
let result = files.map { file in
|
|
1385
|
+
[
|
|
1386
|
+
"name": file.name,
|
|
1387
|
+
"isDirectory": file.isDirectory,
|
|
1388
|
+
"size": file.size,
|
|
1389
|
+
"lastModified": file.lastModified,
|
|
1390
|
+
"attributes": file.attributes as Any
|
|
1391
|
+
]
|
|
1392
|
+
}
|
|
1393
|
+
promise.resolve(result)
|
|
1394
|
+
} catch {
|
|
1395
|
+
promise.reject("SMB_LIST_ERROR", error.localizedDescription)
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
AsyncFunction("smbClientDownload") { (clientId: String, remotePath: String, localPath: String, promise: Promise) in
|
|
1401
|
+
guard let client = self.smbClients[clientId] else {
|
|
1402
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1403
|
+
return
|
|
1404
|
+
}
|
|
1405
|
+
Task {
|
|
1406
|
+
do {
|
|
1407
|
+
let progressDelegate = SmbProgressDelegateImpl(module: self, clientId: clientId)
|
|
1408
|
+
client.setProgressDelegate(progressDelegate)
|
|
1409
|
+
try await client.downloadFile(remotePath: remotePath, localPath: localPath)
|
|
1410
|
+
promise.resolve([
|
|
1411
|
+
"clientId": clientId,
|
|
1412
|
+
"remotePath": remotePath,
|
|
1413
|
+
"localPath": localPath,
|
|
1414
|
+
"downloaded": true
|
|
1415
|
+
])
|
|
1416
|
+
} catch {
|
|
1417
|
+
self.sendEvent("onSmbError", [
|
|
1418
|
+
"clientId": clientId,
|
|
1419
|
+
"error": error.localizedDescription
|
|
1420
|
+
])
|
|
1421
|
+
promise.reject("SMB_DOWNLOAD_ERROR", error.localizedDescription)
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
AsyncFunction("smbClientUpload") { (clientId: String, localPath: String, remotePath: String, promise: Promise) in
|
|
1427
|
+
guard let client = self.smbClients[clientId] else {
|
|
1428
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1429
|
+
return
|
|
1430
|
+
}
|
|
1431
|
+
Task {
|
|
1432
|
+
do {
|
|
1433
|
+
let progressDelegate = SmbProgressDelegateImpl(module: self, clientId: clientId)
|
|
1434
|
+
client.setProgressDelegate(progressDelegate)
|
|
1435
|
+
try await client.uploadFile(localPath: localPath, remotePath: remotePath)
|
|
1436
|
+
promise.resolve([
|
|
1437
|
+
"clientId": clientId,
|
|
1438
|
+
"localPath": localPath,
|
|
1439
|
+
"remotePath": remotePath,
|
|
1440
|
+
"uploaded": true
|
|
1441
|
+
])
|
|
1442
|
+
} catch {
|
|
1443
|
+
self.sendEvent("onSmbError", [
|
|
1444
|
+
"clientId": clientId,
|
|
1445
|
+
"error": error.localizedDescription
|
|
1446
|
+
])
|
|
1447
|
+
promise.reject("SMB_UPLOAD_ERROR", error.localizedDescription)
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
AsyncFunction("smbClientDelete") { (clientId: String, remotePath: String, isDirectory: Bool?, promise: Promise) in
|
|
1453
|
+
guard let client = self.smbClients[clientId] else {
|
|
1454
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1455
|
+
return
|
|
1456
|
+
}
|
|
1457
|
+
Task {
|
|
1458
|
+
do {
|
|
1459
|
+
try await client.deleteFile(remotePath: remotePath, isDirectory: isDirectory ?? false)
|
|
1460
|
+
promise.resolve([
|
|
1461
|
+
"clientId": clientId,
|
|
1462
|
+
"remotePath": remotePath,
|
|
1463
|
+
"deleted": true
|
|
1464
|
+
])
|
|
1465
|
+
} catch {
|
|
1466
|
+
promise.reject("SMB_DELETE_ERROR", error.localizedDescription)
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
AsyncFunction("smbClientCreateDirectory") { (clientId: String, remotePath: String, promise: Promise) in
|
|
1472
|
+
guard let client = self.smbClients[clientId] else {
|
|
1473
|
+
promise.reject("SMB_CLIENT_NOT_FOUND", "SMB client with ID '\(clientId)' not found")
|
|
1474
|
+
return
|
|
1475
|
+
}
|
|
1476
|
+
Task {
|
|
1477
|
+
do {
|
|
1478
|
+
try await client.createDirectory(remotePath: remotePath)
|
|
1479
|
+
promise.resolve([
|
|
1480
|
+
"clientId": clientId,
|
|
1481
|
+
"remotePath": remotePath,
|
|
1482
|
+
"created": true
|
|
1483
|
+
])
|
|
1484
|
+
} catch {
|
|
1485
|
+
promise.reject("SMB_CREATE_DIR_ERROR", error.localizedDescription)
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1119
1490
|
// Enables the module to be used as a native view. Definition components that are accepted as part of
|
|
1120
1491
|
// the view definition: Prop, Events.
|
|
1121
1492
|
View(ReactNativeKookitView.self) {
|
|
@@ -1243,4 +1614,38 @@ private class FtpProgressDelegateImpl: FtpProgressDelegate {
|
|
|
1243
1614
|
"error": error
|
|
1244
1615
|
])
|
|
1245
1616
|
}
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
// Helper class to handle SMB progress callbacks
|
|
1620
|
+
private class SmbProgressDelegateImpl: SmbProgressDelegate {
|
|
1621
|
+
weak var module: ReactNativeKookitModule?
|
|
1622
|
+
let clientId: String
|
|
1623
|
+
|
|
1624
|
+
init(module: ReactNativeKookitModule, clientId: String) {
|
|
1625
|
+
self.module = module
|
|
1626
|
+
self.clientId = clientId
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
func onProgress(transferred: Int64, total: Int64) {
|
|
1630
|
+
let percentage = total > 0 ? Int((transferred * 100) / total) : 0
|
|
1631
|
+
module?.sendEvent("onSmbProgress", [
|
|
1632
|
+
"clientId": clientId,
|
|
1633
|
+
"transferred": transferred,
|
|
1634
|
+
"total": total,
|
|
1635
|
+
"percentage": percentage
|
|
1636
|
+
])
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
func onComplete() {
|
|
1640
|
+
module?.sendEvent("onSmbComplete", [
|
|
1641
|
+
"clientId": clientId
|
|
1642
|
+
])
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
func onError(error: String) {
|
|
1646
|
+
module?.sendEvent("onSmbError", [
|
|
1647
|
+
"clientId": clientId,
|
|
1648
|
+
"error": error
|
|
1649
|
+
])
|
|
1650
|
+
}
|
|
1246
1651
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Pod::Spec.new do |s|
|
|
2
|
+
s.name = 'SMBClient'
|
|
3
|
+
s.version = '0.3.1'
|
|
4
|
+
s.summary = 'SMB2/3 client implementation for iOS/macOS'
|
|
5
|
+
s.description = 'A Swift implementation of SMB2/3 client protocol for iOS and macOS'
|
|
6
|
+
s.homepage = 'https://github.com/kishikawakatsumi/SMBClient'
|
|
7
|
+
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
|
8
|
+
s.author = { 'Kishikawa Katsumi' => 'kishikawakatsumi@mac.com' }
|
|
9
|
+
s.source = { :git => 'https://github.com/kishikawakatsumi/SMBClient.git', :tag => s.version.to_s }
|
|
10
|
+
|
|
11
|
+
s.ios.deployment_target = '13.0'
|
|
12
|
+
s.osx.deployment_target = '10.15'
|
|
13
|
+
s.swift_version = '5.9'
|
|
14
|
+
|
|
15
|
+
s.source_files = 'Sources/SMBClient/**/*'
|
|
16
|
+
|
|
17
|
+
s.frameworks = 'Foundation', 'Network'
|
|
18
|
+
end
|
package/package.json
CHANGED