diff --git a/permission_handler_apple/CHANGELOG.md b/permission_handler_apple/CHANGELOG.md index f60ecef2a..8065518a1 100644 --- a/permission_handler_apple/CHANGELOG.md +++ b/permission_handler_apple/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.4.10 + +* Fixed Info.plist lookup in Package.swift to auto-apply permissions. +* You may see build log "Plugin permission_handler_apple has a Package.swift for ios but is missing a dependency on FlutterFramework". FlutterFramework hasn't been added intentionally because it requires to bump flutter constraint to >=3.41.0. + ## 9.4.9 * Rewrites copyleft code from stackoverflow to fix compliance issue. diff --git a/permission_handler_apple/ios/permission_handler_apple/Package.swift b/permission_handler_apple/ios/permission_handler_apple/Package.swift index 5a9e95281..88170e032 100644 --- a/permission_handler_apple/ios/permission_handler_apple/Package.swift +++ b/permission_handler_apple/ios/permission_handler_apple/Package.swift @@ -21,17 +21,49 @@ import Foundation let env = ProcessInfo.processInfo.environment -/// Walk up from Package.swift looking for Runner/Info.plist. -/// Works when the package is resolved via Flutter's .symlinks/ directory. +func loadInfoPlist(at url: URL) -> [String: Any]? { + NSDictionary(contentsOf: url) as? [String: Any] +} + +/// Find the host app's Runner/Info.plist. +/// +/// Flutter can resolve this package through a local plugin path, a generated +/// SPM package, or an Xcode package cache. Look for a Flutter app root by +/// walking up from the package and current working directory, using pubspec.yaml +/// next to ios/Runner/Info.plist as the app-root anchor. func findInfoPlist() -> [String: Any] { - var dir = URL(fileURLWithPath: #file).deletingLastPathComponent() - for _ in 0..<8 { - let candidate = dir.appendingPathComponent("Runner/Info.plist") - if let plist = NSDictionary(contentsOf: candidate) as? [String: Any] { - return plist + let fileManager = FileManager.default + + let packageDir = URL(fileURLWithPath: #file).deletingLastPathComponent() + let currentDir = URL(fileURLWithPath: fileManager.currentDirectoryPath) + + var visited = Set() + + for root in [packageDir, currentDir] { + var dir = root + + for _ in 0..<10 { + let key = dir.resolvingSymlinksInPath().path + guard visited.insert(key).inserted else { + break + } + + let pubspecURL = dir.appendingPathComponent("pubspec.yaml") + let plistURL = dir.appendingPathComponent("ios/Runner/Info.plist") + + if fileManager.fileExists(atPath: pubspecURL.path), + let plist = loadInfoPlist(at: plistURL) { + return plist + } + + let parent = dir.deletingLastPathComponent() + if parent.path == dir.path { + break + } + dir = parent } - dir = dir.deletingLastPathComponent() } + return [:] } @@ -137,9 +169,11 @@ let package = Package( products: [ .library(name: "permission-handler-apple", targets: ["permission_handler_apple"]), ], + dependencies: [], targets: [ .target( name: "permission_handler_apple", + dependencies: [], path: "Sources/permission_handler_apple", resources: [ .process("PrivacyInfo.xcprivacy"), diff --git a/permission_handler_apple/pubspec.yaml b/permission_handler_apple/pubspec.yaml index a03947478..97963c0ea 100644 --- a/permission_handler_apple/pubspec.yaml +++ b/permission_handler_apple/pubspec.yaml @@ -2,7 +2,7 @@ name: permission_handler_apple description: Permission plugin for Flutter. This plugin provides the iOS API to request and check permissions. repository: https://github.com/baseflow/flutter-permission-handler issue_tracker: https://github.com/Baseflow/flutter-permission-handler/issues -version: 9.4.9 +version: 9.4.10 environment: sdk: ">=2.18.0 <4.0.0"