Created
May 14, 2023 17:15
-
-
Save bierbaumtim/63c5057fc2889558d1801d95d93b6c6c to your computer and use it in GitHub Desktop.
Flutter iOS Keychain Availability Handler
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
import 'dart:async'; | |
import 'package:flutter/services.dart'; | |
class SecureStorageService { | |
static const MethodChannel _channel = | |
MethodChannel('com.example.test/secstore/commands'); | |
static const _eventChannel = | |
EventChannel('com.example.test/secstore/events'); | |
late Stream<dynamic> _eventsFetch; | |
Stream<bool> get onNotificationRecieved => _eventsFetch | |
.where((event) => event is bool) | |
.map((event) => event as bool); | |
SecureStorageService() { | |
_eventsFetch = _eventChannel.receiveBroadcastStream(); | |
} | |
Future<bool> isProtectedDataAvailable() async { | |
try { | |
final result = await _channel.invokeMethod<bool>( | |
'isProtectedDataAvailable', | |
); | |
return result ?? false; | |
} on PlatformException catch (_) { | |
return false; | |
} | |
} | |
} |
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
import Flutter | |
import UIKit | |
import os.log | |
public class SecureStorageDelegate: NSObject, FlutterPlugin, FlutterStreamHandler { | |
public static func register(with registrar: FlutterPluginRegistrar) { | |
let channel = FlutterMethodChannel(name: "com.example.test/secstore/commands", binaryMessenger: registrar.messenger()) | |
let secStoreEventChannel = FlutterEventChannel(name: "com.example.test/secstore/events", binaryMessenger: registrar.messenger()) | |
let instance = SecureStorageDelegate() | |
registrar.addMethodCallDelegate(instance, channel: channel) | |
registrar.addApplicationDelegate(instance) | |
secStoreEventChannel.setStreamHandler(instance) | |
} | |
private var secStoreAvailabilitySink: FlutterEventSink? | |
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { | |
os_log("handle %@ on SecureStorageDelegate", call.method) | |
switch call.method { | |
case "isProtectedDataAvailable": | |
result(UIApplication.shared.isProtectedDataAvailable) | |
default: | |
result(FlutterMethodNotImplemented) | |
} | |
} | |
public func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) { | |
guard let sink = secStoreAvailabilitySink else { | |
os_log("secStoreAvailabilitySink is null", type: OSLogType.error) | |
return | |
} | |
sink(true) | |
} | |
public func applicationProtectedDataWillBecomeUnavailable(_ application: UIApplication) { | |
guard let sink = secStoreAvailabilitySink else { | |
os_log("secStoreAvailabilitySink is null", type: OSLogType.error) | |
return | |
} | |
sink(false) | |
} | |
public func onListen(withArguments arguments: Any?, | |
eventSink: @escaping FlutterEventSink) -> FlutterError? { | |
self.secStoreAvailabilitySink = eventSink | |
os_log("set eventSink") | |
return nil | |
} | |
public func onCancel(withArguments arguments: Any?) -> FlutterError? { | |
secStoreAvailabilitySink = nil | |
return nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment