From d338d42a756cd9758db48c6ece9e5d871b87f142 Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Tue, 29 Aug 2023 21:37:13 +0800 Subject: [PATCH] Impl platform lock on ios --- np_platform_lock/.metadata | 13 ++-- np_platform_lock/ios/.gitignore | 38 ++++++++++ np_platform_lock/ios/Assets/.gitkeep | 0 np_platform_lock/ios/Classes/K.swift | 5 ++ .../ios/Classes/LockChannelHandler.swift | 73 +++++++++++++++++++ .../ios/Classes/NpPlatformLockPlugin.swift | 13 ++++ np_platform_lock/ios/Classes/Util.swift | 35 +++++++++ np_platform_lock/ios/np_platform_lock.podspec | 23 ++++++ np_platform_lock/pubspec.yaml | 2 + 9 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 np_platform_lock/ios/.gitignore create mode 100644 np_platform_lock/ios/Assets/.gitkeep create mode 100644 np_platform_lock/ios/Classes/K.swift create mode 100644 np_platform_lock/ios/Classes/LockChannelHandler.swift create mode 100644 np_platform_lock/ios/Classes/NpPlatformLockPlugin.swift create mode 100644 np_platform_lock/ios/Classes/Util.swift create mode 100644 np_platform_lock/ios/np_platform_lock.podspec diff --git a/np_platform_lock/.metadata b/np_platform_lock/.metadata index b0ed2b59..9c0286ed 100644 --- a/np_platform_lock/.metadata +++ b/np_platform_lock/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled. version: - revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + revision: f72efea43c3013323d1b95cff571f3c1caa37583 channel: stable project_type: plugin @@ -13,11 +13,14 @@ project_type: plugin migration: platforms: - platform: root - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + create_revision: f72efea43c3013323d1b95cff571f3c1caa37583 + base_revision: f72efea43c3013323d1b95cff571f3c1caa37583 - platform: android - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + create_revision: f72efea43c3013323d1b95cff571f3c1caa37583 + base_revision: f72efea43c3013323d1b95cff571f3c1caa37583 + - platform: ios + create_revision: f72efea43c3013323d1b95cff571f3c1caa37583 + base_revision: f72efea43c3013323d1b95cff571f3c1caa37583 # User provided section diff --git a/np_platform_lock/ios/.gitignore b/np_platform_lock/ios/.gitignore new file mode 100644 index 00000000..0c885071 --- /dev/null +++ b/np_platform_lock/ios/.gitignore @@ -0,0 +1,38 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig +/Flutter/ephemeral/ +/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/np_platform_lock/ios/Assets/.gitkeep b/np_platform_lock/ios/Assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/np_platform_lock/ios/Classes/K.swift b/np_platform_lock/ios/Classes/K.swift new file mode 100644 index 00000000..1f79ead4 --- /dev/null +++ b/np_platform_lock/ios/Classes/K.swift @@ -0,0 +1,5 @@ +import Foundation + +struct K { + static let libId = "com.nkming.nc_photos.np_platform_lock" +} diff --git a/np_platform_lock/ios/Classes/LockChannelHandler.swift b/np_platform_lock/ios/Classes/LockChannelHandler.swift new file mode 100644 index 00000000..69ede183 --- /dev/null +++ b/np_platform_lock/ios/Classes/LockChannelHandler.swift @@ -0,0 +1,73 @@ +import Flutter +import Foundation + +class LockChannelHandler { + func onMethodCall(call: FlutterMethodCall, result: FlutterResult) { + let args = call.arguments as? Dictionary + do { + switch call.method { + case "tryLock": + try tryLock( + lockId: (args?["lockId"] as? Int).unwrap(), + result: result + ) + + case "unlock": + try unlock( + lockId: (args?["lockId"] as? Int).unwrap(), + result: result + ) + + default: + result(FlutterMethodNotImplemented) + } + } catch let error as AppError { + result( + FlutterError( + code: "systemException", + message: error.message, + details: "\(error.stackTrace)" + ) + ) + } catch { + result( + FlutterError( + code: "systemException", + message: "\(error)", + details: nil + ) + ) + } + } + + private func tryLock(lockId: Int, result: FlutterResult) { + if LockChannelHandler.locks[lockId] != true { + LockChannelHandler.locks[lockId] = true + lockedIds += [lockId] + result(true) + } else { + result(false) + } + } + + private func unlock(lockId: Int, result: FlutterResult) { + if LockChannelHandler.locks[lockId] == true { + LockChannelHandler.locks[lockId] = false + lockedIds.removeAll(where: { $0 == lockId }) + result(nil) + } else { + result( + FlutterError( + code: "notLockedException", + message: "Cannot unlock without first locking", + details: nil + ) + ) + } + } + + private var lockedIds: [Int] = [] + + static let methodChannel = "\(K.libId)/lock" + private static var locks: [Int:Bool] = [:] +} diff --git a/np_platform_lock/ios/Classes/NpPlatformLockPlugin.swift b/np_platform_lock/ios/Classes/NpPlatformLockPlugin.swift new file mode 100644 index 00000000..1fe52ddb --- /dev/null +++ b/np_platform_lock/ios/Classes/NpPlatformLockPlugin.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +public class NpPlatformLockPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let lockHandler = LockChannelHandler() + let lockChannel = FlutterMethodChannel( + name: LockChannelHandler.methodChannel, + binaryMessenger: registrar.messenger() + ) + lockChannel.setMethodCallHandler(lockHandler.onMethodCall) + } +} diff --git a/np_platform_lock/ios/Classes/Util.swift b/np_platform_lock/ios/Classes/Util.swift new file mode 100644 index 00000000..a3f17c05 --- /dev/null +++ b/np_platform_lock/ios/Classes/Util.swift @@ -0,0 +1,35 @@ +import Foundation + +class AppError: Error { + init(_ message: String? = nil, stackTrace: [String] = Thread.callStackSymbols) { + self.message_ = message + self.stackTrace = stackTrace.joined(separator: "\n") + } + + var description: String { + return "\(message_ ?? "") (throw: \(String(describing: self))\nStack trace:\n\(stackTrace)" + } + + var message: String { + return message_ == nil ? String(describing: self) : message_! + } + + let stackTrace: String + private let message_: String? +} + +class NilError: AppError { +} + +extension Optional { + func unwrap( + _ errorBuilder: (() -> Error)? = nil, + file: String = #fileID, + line: Int = #line + ) throws -> Wrapped { + guard let value = self else { + throw errorBuilder?() ?? NilError("\(type(of: self)) is nil in \(file):\(line)") + } + return value + } +} diff --git a/np_platform_lock/ios/np_platform_lock.podspec b/np_platform_lock/ios/np_platform_lock.podspec new file mode 100644 index 00000000..1fb1cbd7 --- /dev/null +++ b/np_platform_lock/ios/np_platform_lock.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint np_platform_lock.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'np_platform_lock' + s.version = '0.0.1' + s.summary = 'A new Flutter plugin project.' + s.description = <<-DESC +A new Flutter plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '9.0' + + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } + s.swift_version = '5.0' +end diff --git a/np_platform_lock/pubspec.yaml b/np_platform_lock/pubspec.yaml index b775d146..14bb3650 100644 --- a/np_platform_lock/pubspec.yaml +++ b/np_platform_lock/pubspec.yaml @@ -25,3 +25,5 @@ flutter: android: package: com.nkming.nc_photos.np_platform_lock pluginClass: NpPlatformLockPlugin + ios: + pluginClass: NpPlatformLockPlugin