diff --git a/.gitignore b/.gitignore
index e9dc58d..911a8de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,16 @@
.pub/
build/
+.build/
+.swiftpm/
+
+# Firebase — contains developer email, OAuth metadata, internal endpoints
+firebase-debug.log
+
+# IntelliJ/IDE backup and generated files
+*.bak
+*.iml
+.idea/
+
+# Flutter iOS ephemeral (generated per-build, may contain absolute local paths)
+example/ios/Flutter/ephemeral/
diff --git a/.idea/libraries/Dart_SDK.xml b/.idea/libraries/Dart_SDK.xml
deleted file mode 100644
index 7d5efcd..0000000
--- a/.idea/libraries/Dart_SDK.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.pubignore b/.pubignore
new file mode 100644
index 0000000..9eef9a1
--- /dev/null
+++ b/.pubignore
@@ -0,0 +1,6 @@
+build/
+.idea/
+*.iml
+*.bak
+firebase-debug.log
+example/ios/Flutter/ephemeral/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dbfd18c..b25ebdd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
-# 2.1.0
+# 3.0.0
+* breaking: add Swift Package Manager support for iOS plugins
+* breaking: raise minimum support to Dart 3.11+, Flutter 3.41+, and iOS 13+
+* support: keep CocoaPods compatibility while adding Swift Package Manager packaging
+
+## 2.1.0
* fix: #4
## 2.0.1
diff --git a/README.md b/README.md
index d31300c..5abf5ad 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,10 @@
Retrieve Android/iOS device user agents in Flutter.
+iOS now supports both Swift Package Manager and CocoaPods.
+
+This release raises the minimum supported toolchain to Dart 3.11+, Flutter 3.41+, and iOS 13+.
+
### Example user-agents:
| System | User-Agent | WebView User-Agent |
@@ -42,4 +46,4 @@ Android version returns:
### Credits 👍
-Based of https://github.com/j0j00/flutter_user_agent
\ No newline at end of file
+Based of https://github.com/j0j00/flutter_user_agent
diff --git a/example/.gitignore b/example/.gitignore
index 0fa6b67..caaf16a 100644
--- a/example/.gitignore
+++ b/example/.gitignore
@@ -44,3 +44,10 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
+
+# Flutter iOS — generated per-build, may contain absolute local paths / OAuth metadata
+ios/Flutter/ephemeral/
+ios/Flutter/flutter_export_environment.sh
+
+# Firebase debug log — contains developer email and OAuth metadata
+firebase-debug.log
diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist
index 9367d48..391a902 100644
--- a/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/example/ios/Flutter/AppFrameworkInfo.plist
@@ -20,7 +20,5 @@
????
CFBundleVersion
1.0
- MinimumOSVersion
- 8.0
diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig
index ec97fc6..592ceee 100644
--- a/example/ios/Flutter/Debug.xcconfig
+++ b/example/ios/Flutter/Debug.xcconfig
@@ -1,2 +1 @@
-#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig
index c4855bf..592ceee 100644
--- a/example/ios/Flutter/Release.xcconfig
+++ b/example/ios/Flutter/Release.xcconfig
@@ -1,2 +1 @@
-#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
diff --git a/example/ios/Podfile b/example/ios/Podfile
deleted file mode 100644
index f7d6a5e..0000000
--- a/example/ios/Podfile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Uncomment this line to define a global platform for your project
-# platform :ios, '9.0'
-
-# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
-ENV['COCOAPODS_DISABLE_STATS'] = 'true'
-
-project 'Runner', {
- 'Debug' => :debug,
- 'Profile' => :release,
- 'Release' => :release,
-}
-
-def flutter_root
- generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
- unless File.exist?(generated_xcode_build_settings_path)
- raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
- end
-
- File.foreach(generated_xcode_build_settings_path) do |line|
- matches = line.match(/FLUTTER_ROOT\=(.*)/)
- return matches[1].strip if matches
- end
- raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
-end
-
-require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
-
-flutter_ios_podfile_setup
-
-target 'Runner' do
- flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
-end
-
-post_install do |installer|
- installer.pods_project.targets.each do |target|
- flutter_additional_ios_build_settings(target)
- end
-end
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
deleted file mode 100644
index bd94aa0..0000000
--- a/example/ios/Podfile.lock
+++ /dev/null
@@ -1,22 +0,0 @@
-PODS:
- - fk_user_agent (2.0.0):
- - Flutter
- - Flutter (1.0.0)
-
-DEPENDENCIES:
- - fk_user_agent (from `.symlinks/plugins/fk_user_agent/ios`)
- - Flutter (from `Flutter`)
-
-EXTERNAL SOURCES:
- fk_user_agent:
- :path: ".symlinks/plugins/fk_user_agent/ios"
- Flutter:
- :path: Flutter
-
-SPEC CHECKSUMS:
- fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
- Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
-
-PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d
-
-COCOAPODS: 1.10.1
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 9c68879..95f271d 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,13 +3,13 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
- 85A618B28BC7FABA93E3AB01 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 73E6B311D8DE1E2206C57141 /* libPods-Runner.a */; };
+ 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
@@ -34,9 +34,9 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
- 48C0D7608BE73E326DE5C79E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
- 560661FA8E080455ADDEE653 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
- 73E6B311D8DE1E2206C57141 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; };
+ 78DABEA22ED26510000E7860 /* fk_user_agent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = fk_user_agent; path = ../../ios/fk_user_agent; sourceTree = ""; };
+ 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
@@ -48,7 +48,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- DD7B8A60E2A7402BA6E6098E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -56,35 +55,19 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 85A618B28BC7FABA93E3AB01 /* libPods-Runner.a in Frameworks */,
+ 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 17E06F9FD7C8897F04046A74 /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 73E6B311D8DE1E2206C57141 /* libPods-Runner.a */,
- );
- name = Frameworks;
- sourceTree = "";
- };
- 79916955F1AA8E1535843181 /* Pods */ = {
- isa = PBXGroup;
- children = (
- DD7B8A60E2A7402BA6E6098E /* Pods-Runner.debug.xcconfig */,
- 48C0D7608BE73E326DE5C79E /* Pods-Runner.release.xcconfig */,
- 560661FA8E080455ADDEE653 /* Pods-Runner.profile.xcconfig */,
- );
- name = Pods;
- path = Pods;
- sourceTree = "";
- };
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
+ 78DABEA22ED26510000E7860 /* fk_user_agent */,
+ 784666492D4C4C64000A1A5F /* FlutterFramework */,
+ 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
@@ -99,8 +82,6 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
- 79916955F1AA8E1535843181 /* Pods */,
- 17E06F9FD7C8897F04046A74 /* Frameworks */,
);
sourceTree = "";
};
@@ -143,7 +124,6 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
- 8A7B39775DC5546369E54F7A /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
@@ -156,6 +136,9 @@
dependencies = (
);
name = Runner;
+ packageProductDependencies = (
+ 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
+ );
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
@@ -166,7 +149,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1020;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -183,6 +166,9 @@
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
+ packageReferences = (
+ 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
+ );
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
@@ -209,10 +195,12 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
@@ -221,30 +209,9 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
- 8A7B39775DC5546369E54F7A /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@@ -333,7 +300,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -350,7 +317,10 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = io.flutterfastkit.fkUserAgentExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
@@ -404,7 +374,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -453,7 +423,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -470,7 +440,10 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = io.flutterfastkit.fkUserAgentExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
@@ -485,7 +458,10 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = io.flutterfastkit.fkUserAgentExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
@@ -516,6 +492,20 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
+
+/* Begin XCLocalSwiftPackageReference section */
+ 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
+ isa = XCLocalSwiftPackageReference;
+ relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
+ };
+/* End XCLocalSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = FlutterGeneratedPluginSwiftPackage;
+ };
+/* End XCSwiftPackageProductDependency section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index a28140c..0bd6d42 100644
--- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,10 +1,28 @@
+
+
+
+
+
+
+
+
+
+
@@ -45,11 +64,13 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
+ enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata
index 21a3cc1..1d526a1 100644
--- a/example/ios/Runner.xcworkspace/contents.xcworkspacedata
+++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -4,7 +4,4 @@
-
-
diff --git a/example/ios/Runner/AppDelegate.h b/example/ios/Runner/AppDelegate.h
index 36e21bb..01e6e1d 100644
--- a/example/ios/Runner/AppDelegate.h
+++ b/example/ios/Runner/AppDelegate.h
@@ -1,6 +1,6 @@
#import
#import
-@interface AppDelegate : FlutterAppDelegate
+@interface AppDelegate : FlutterAppDelegate
@end
diff --git a/example/ios/Runner/AppDelegate.m b/example/ios/Runner/AppDelegate.m
index 70e8393..cebafc9 100644
--- a/example/ios/Runner/AppDelegate.m
+++ b/example/ios/Runner/AppDelegate.m
@@ -5,9 +5,12 @@ @implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- [GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
+- (void)didInitializeImplicitFlutterEngine:(NSObject*)engineBridge {
+ [GeneratedPluginRegistrant registerWithRegistry:engineBridge.pluginRegistry];
+}
+
@end
diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist
index 9336ef5..f76e30d 100644
--- a/example/ios/Runner/Info.plist
+++ b/example/ios/Runner/Info.plist
@@ -2,6 +2,8 @@
+ CADisableMinimumFrameDurationOnPhone
+
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
@@ -22,6 +24,29 @@
$(FLUTTER_BUILD_NUMBER)
LSRequiresIPhoneOS
+ UIApplicationSceneManifest
+
+ UIApplicationSupportsMultipleScenes
+
+ UISceneConfigurations
+
+ UIWindowSceneSessionRoleApplication
+
+
+ UISceneClassName
+ UIWindowScene
+ UISceneConfigurationName
+ flutter
+ UISceneDelegateClassName
+ FlutterSceneDelegate
+ UISceneStoryboardFile
+ Main
+
+
+
+
+ UIApplicationSupportsIndirectInputEvents
+
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 003e17c..0641787 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -19,7 +19,7 @@ class _MyAppState extends State {
@override
void initState() {
super.initState();
- WidgetsBinding.instance?.addPostFrameCallback((timeStamp) async {
+ WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await FkUserAgent.init();
initPlatformState();
});
@@ -50,12 +50,8 @@ class _MyAppState extends State {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
- appBar: AppBar(
- title: const Text('Plugin example app'),
- ),
- body: Center(
- child: Text('Running on: $_platformVersion\n'),
- ),
+ appBar: AppBar(title: const Text('Plugin example app')),
+ body: Center(child: Text('Running on: $_platformVersion\n')),
),
);
}
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 6dd4be9..63aadb0 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -5,65 +5,65 @@ packages:
dependency: transitive
description:
name: async
- url: "https://pub.flutter-io.cn"
+ sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
+ url: "https://pub.dev"
source: hosted
- version: "2.5.0"
+ version: "2.13.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.flutter-io.cn"
+ sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.2"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.flutter-io.cn"
+ sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.flutter-io.cn"
- source: hosted
- version: "1.2.0"
+ version: "1.4.1"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.flutter-io.cn"
+ sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.flutter-io.cn"
+ sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
+ url: "https://pub.dev"
source: hosted
- version: "1.15.0"
+ version: "1.19.1"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
- url: "https://pub.flutter-io.cn"
+ sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
+ url: "https://pub.dev"
source: hosted
- version: "1.0.2"
+ version: "1.0.9"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.flutter-io.cn"
+ sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.3.3"
fk_user_agent:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
- version: "2.0.0"
+ version: "3.0.0"
flutter:
dependency: "direct main"
description: flutter
@@ -74,88 +74,131 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
+ url: "https://pub.dev"
+ source: hosted
+ version: "11.0.2"
+ leak_tracker_flutter_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_flutter_testing
+ sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.10"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.2"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.flutter-io.cn"
+ sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.12.19"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
+ url: "https://pub.dev"
source: hosted
- version: "0.12.10"
+ version: "0.13.0"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.flutter-io.cn"
+ sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
+ url: "https://pub.dev"
source: hosted
- version: "1.3.0"
+ version: "1.18.0"
path:
dependency: transitive
description:
name: path
- url: "https://pub.flutter-io.cn"
+ sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.9.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
- version: "0.0.99"
+ version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
- url: "https://pub.flutter-io.cn"
+ sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.10.2"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.flutter-io.cn"
+ sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
+ url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.flutter-io.cn"
+ sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.4"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.flutter-io.cn"
+ sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.4.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.flutter-io.cn"
+ sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.flutter-io.cn"
+ sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
+ url: "https://pub.dev"
source: hosted
- version: "0.2.19"
- typed_data:
+ version: "0.7.11"
+ vector_math:
dependency: transitive
description:
- name: typed_data
- url: "https://pub.flutter-io.cn"
+ name: vector_math
+ sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
+ url: "https://pub.dev"
source: hosted
- version: "1.3.0"
- vector_math:
+ version: "2.2.0"
+ vm_service:
dependency: transitive
description:
- name: vector_math
- url: "https://pub.flutter-io.cn"
+ name: vm_service
+ sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "15.2.0"
sdks:
- dart: ">=2.12.0 <3.0.0"
- flutter: ">=2.0.0"
+ dart: ">=3.11.0 <4.0.0"
+ flutter: ">=3.41.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index d4a032d..8a3568c 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -6,7 +6,7 @@ description: Demonstrates how to use the fk_user_agent plugin.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
- sdk: ">=2.12.0 <3.0.0"
+ sdk: ^3.11.0
dependencies:
flutter:
diff --git a/fk_user_agent.iml b/fk_user_agent.iml
index be36c1d..3c78e7e 100644
--- a/fk_user_agent.iml
+++ b/fk_user_agent.iml
@@ -1,17 +1,18 @@
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/ios/Assets/.gitkeep b/ios/Assets/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/ios/fk_user_agent.podspec b/ios/fk_user_agent.podspec
index 60cbe9e..29b590e 100644
--- a/ios/fk_user_agent.podspec
+++ b/ios/fk_user_agent.podspec
@@ -4,19 +4,19 @@
#
Pod::Spec.new do |s|
s.name = 'fk_user_agent'
- s.version = '2.0.0'
- s.summary = 'A new Flutter project.'
+ s.version = '3.0.0'
+ s.summary = 'Flutter plugin for retrieving device user agents.'
s.description = <<-DESC
-Retrieve Android/iOS device user agents in Flutter.
+Retrieve Android and iOS device user agents, including WebView user agents, from Flutter.
DESC
s.homepage = 'https://github.com/flutter-fast-kit/fk_user_agent'
- s.license = { :file => '../LICENSE' }
+ s.license = { :type => 'MIT', :file => '../LICENSE' }
s.author = { 'lunnnnul' => 'lunnnnul@gmail.com' }
- s.source = { :path => '.' }
- s.source_files = 'Classes/**/*'
- s.public_header_files = 'Classes/**/*.h'
+ s.source = { :git => 'https://github.com/flutter-fast-kit/fk_user_agent.git', :tag => s.version.to_s }
+ s.source_files = 'fk_user_agent/Sources/fk_user_agent/**/*.{h,m}'
+ s.public_header_files = 'fk_user_agent/Sources/fk_user_agent/include/**/*.h'
s.dependency 'Flutter'
- s.platform = :ios, '8.0'
+ s.platform = :ios, '13.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
diff --git a/ios/fk_user_agent/Package.swift b/ios/fk_user_agent/Package.swift
new file mode 100644
index 0000000..0f417a1
--- /dev/null
+++ b/ios/fk_user_agent/Package.swift
@@ -0,0 +1,27 @@
+// swift-tools-version: 5.9
+
+import PackageDescription
+
+let package = Package(
+ name: "fk_user_agent",
+ platforms: [
+ .iOS("13.0")
+ ],
+ products: [
+ .library(name: "fk-user-agent", targets: ["fk_user_agent"])
+ ],
+ dependencies: [
+ .package(name: "FlutterFramework", path: "../FlutterFramework")
+ ],
+ targets: [
+ .target(
+ name: "fk_user_agent",
+ dependencies: [
+ .product(name: "FlutterFramework", package: "FlutterFramework")
+ ],
+ cSettings: [
+ .headerSearchPath("include/fk_user_agent")
+ ]
+ )
+ ]
+)
diff --git a/ios/Classes/FkUserAgentPlugin.m b/ios/fk_user_agent/Sources/fk_user_agent/FkUserAgentPlugin.m
similarity index 99%
rename from ios/Classes/FkUserAgentPlugin.m
rename to ios/fk_user_agent/Sources/fk_user_agent/FkUserAgentPlugin.m
index 2bea706..bd57e3a 100644
--- a/ios/Classes/FkUserAgentPlugin.m
+++ b/ios/fk_user_agent/Sources/fk_user_agent/FkUserAgentPlugin.m
@@ -1,4 +1,4 @@
-#import "FkUserAgentPlugin.h"
+#import "./include/fk_user_agent/FkUserAgentPlugin.h"
@implementation FkUserAgentPlugin
diff --git a/ios/Classes/FkUserAgentPlugin.h b/ios/fk_user_agent/Sources/fk_user_agent/include/fk_user_agent/FkUserAgentPlugin.h
similarity index 100%
rename from ios/Classes/FkUserAgentPlugin.h
rename to ios/fk_user_agent/Sources/fk_user_agent/include/fk_user_agent/FkUserAgentPlugin.h
diff --git a/lib/fk_user_agent.dart b/lib/fk_user_agent.dart
index 22c8183..4fda37b 100644
--- a/lib/fk_user_agent.dart
+++ b/lib/fk_user_agent.dart
@@ -13,7 +13,7 @@ class FkUserAgent {
///
/// Set [force] to true if you want to refetch the user agent properties from
/// the native platform.
- static Future init({force: false}) async {
+ static Future init({bool force = false}) async {
if (_properties == null || force) {
_properties = Map.unmodifiable(await (_channel.invokeMethod('getProperties')));
}
@@ -41,7 +41,7 @@ class FkUserAgent {
}
/// Fetch a [property] asynchronously that can be used to build your own user agent string.
- static dynamic getPropertyAsync(String property) async {
+ static Future getPropertyAsync(String property) async {
await init();
return _properties![property];
}
diff --git a/pubspec.lock b/pubspec.lock
index 6c77e39..b3f9beb 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,51 +5,50 @@ packages:
dependency: transitive
description:
name: async
- url: "https://pub.flutter-io.cn"
+ sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
+ url: "https://pub.dev"
source: hosted
- version: "2.5.0"
+ version: "2.13.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.flutter-io.cn"
+ sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.2"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.flutter-io.cn"
+ sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.flutter-io.cn"
- source: hosted
- version: "1.2.0"
+ version: "1.4.1"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.flutter-io.cn"
+ sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.flutter-io.cn"
+ sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
+ url: "https://pub.dev"
source: hosted
- version: "1.15.0"
+ version: "1.19.1"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.flutter-io.cn"
+ sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.3.3"
flutter:
dependency: "direct main"
description: flutter
@@ -60,88 +59,131 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
+ url: "https://pub.dev"
+ source: hosted
+ version: "11.0.2"
+ leak_tracker_flutter_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_flutter_testing
+ sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.10"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.2"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.flutter-io.cn"
+ sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.12.19"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
+ url: "https://pub.dev"
source: hosted
- version: "0.12.10"
+ version: "0.13.0"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.flutter-io.cn"
+ sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
+ url: "https://pub.dev"
source: hosted
- version: "1.3.0"
+ version: "1.18.0"
path:
dependency: transitive
description:
name: path
- url: "https://pub.flutter-io.cn"
+ sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.9.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
- version: "0.0.99"
+ version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
- url: "https://pub.flutter-io.cn"
+ sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.10.2"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.flutter-io.cn"
+ sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
+ url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.flutter-io.cn"
+ sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.4"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.flutter-io.cn"
+ sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.4.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.flutter-io.cn"
+ sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.flutter-io.cn"
+ sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
+ url: "https://pub.dev"
source: hosted
- version: "0.2.19"
- typed_data:
+ version: "0.7.11"
+ vector_math:
dependency: transitive
description:
- name: typed_data
- url: "https://pub.flutter-io.cn"
+ name: vector_math
+ sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
+ url: "https://pub.dev"
source: hosted
- version: "1.3.0"
- vector_math:
+ version: "2.2.0"
+ vm_service:
dependency: transitive
description:
- name: vector_math
- url: "https://pub.flutter-io.cn"
+ name: vm_service
+ sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "15.2.0"
sdks:
- dart: ">=2.12.0 <3.0.0"
- flutter: ">=2.0.0"
+ dart: ">=3.11.0 <4.0.0"
+ flutter: ">=3.41.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index f3e54f6..b25fd68 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,11 @@
name: fk_user_agent
description: Retrieve Android/iOS device user agents in Flutter.
-version: 2.1.0
+version: 3.0.0
homepage: https://github.com/flutter-fast-kit/fk_user_agent
environment:
- sdk: ">=2.12.0 <3.0.0"
- flutter: ">=2.0.0"
+ sdk: ^3.11.0
+ flutter: ">=3.41.0"
dependencies:
flutter:
diff --git a/test/fk_user_agent_test.dart b/test/fk_user_agent_test.dart
index ea86cf1..ae2cc29 100644
--- a/test/fk_user_agent_test.dart
+++ b/test/fk_user_agent_test.dart
@@ -1,3 +1,4 @@
+import 'package:fk_user_agent/fk_user_agent.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -6,17 +7,72 @@ void main() {
TestWidgetsFlutterBinding.ensureInitialized();
+ late int invocationCount;
+
+ Map responseForCall(int callNumber) {
+ return {
+ 'userAgent': 'agent-$callNumber',
+ 'webViewUserAgent': 'web-$callNumber',
+ 'buildNumber': '$callNumber',
+ };
+ }
+
setUp(() {
- channel.setMockMethodCallHandler((MethodCall methodCall) async {
- return '42';
+ invocationCount = 0;
+ FkUserAgent.release();
+ TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
+ .setMockMethodCallHandler(channel, (MethodCall methodCall) async {
+ expect(methodCall.method, 'getProperties');
+ invocationCount += 1;
+ return responseForCall(invocationCount);
});
});
tearDown(() {
- channel.setMockMethodCallHandler(null);
+ FkUserAgent.release();
+ TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
+ .setMockMethodCallHandler(channel, null);
+ });
+
+ test('init caches properties and populates getters', () async {
+ await FkUserAgent.init();
+ await FkUserAgent.init();
+
+ expect(invocationCount, 1);
+ expect(FkUserAgent.userAgent, 'agent-1');
+ expect(FkUserAgent.webViewUserAgent, 'web-1');
+ expect(FkUserAgent.getProperty('buildNumber'), '1');
+ });
+
+ test('force init refetches native properties', () async {
+ await FkUserAgent.init();
+ await FkUserAgent.init(force: true);
+
+ expect(invocationCount, 2);
+ expect(FkUserAgent.userAgent, 'agent-2');
});
- test('getPlatformVersion', () async {
- // expect(await FkUserAgent.platformVersion, '42');
+ test('release clears cached properties', () async {
+ await FkUserAgent.init();
+
+ FkUserAgent.release();
+
+ expect(FkUserAgent.properties, isNull);
+ });
+
+ test('getPropertyAsync initializes lazily', () async {
+ final dynamic buildNumber = await FkUserAgent.getPropertyAsync('buildNumber');
+
+ expect(invocationCount, 1);
+ expect(buildNumber, '1');
+ });
+
+ test('properties map is unmodifiable', () async {
+ await FkUserAgent.init();
+
+ expect(
+ () => FkUserAgent.properties!['anotherKey'] = 'value',
+ throwsUnsupportedError,
+ );
});
}