├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── LocalePlusPlugin.h │ ├── LocalePlusPlugin.m │ ├── MethodNames.swift │ └── SwiftLocalePlusPlugin.swift ├── .gitignore └── locale_plus.podspec ├── android ├── settings.gradle ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── gokberkbar │ │ └── locale_plus │ │ ├── MethodNames.java │ │ └── LocalePlusPlugin.java ├── build.gradle └── gradlew ├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── Podfile.lock │ ├── .gitignore │ └── Podfile ├── README.md ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── locale_plus_example │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle.kts │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── build.gradle.kts │ └── settings.gradle.kts ├── pubspec.yaml ├── .gitignore ├── analysis_options.yaml ├── .metadata ├── lib │ └── main.dart └── pubspec.lock ├── .github └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── pubspec.yaml ├── LICENSE ├── .metadata ├── CHANGELOG.md ├── lib ├── locale_plus_platform_interface.dart ├── locale_plus.dart ├── locale_plus_method_channel.dart └── patch_all_locales.dart ├── README.md └── analysis_options.yaml /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'locale_plus' 2 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Locale Plus Example 2 | 3 | Demonstrates how to use the locale_plus plugin. 4 | 5 | -------------------------------------------------------------------------------- /ios/Classes/LocalePlusPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface LocalePlusPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokberkbar/locale_plus/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/locale_plus_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.locale_plus_example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip 6 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | .cxx/ 9 | 10 | # Remember to never publicly share your keystore. 11 | # See https://flutter.dev/to/reference-keystore 12 | key.properties 13 | **/*.keystore 14 | **/*.jks 15 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Replace this paragraph with a description of PR* 2 | 3 | ## Pre-launch Checklist 4 | 5 | - [ ] I updated `pubspec.yaml` with an appropriate new version. 6 | - [ ] I updated `CHANGELOG.md` with new version number and description. 7 | - [ ] I updated `README.md`. 8 | - [ ] I updated example project with new feature. 9 | - [ ] Check if the branch name is correct. 10 | - [ ] Code is warning free. 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: locale_plus_example 2 | description: Demonstrates how to use the locale_plus plugin. 3 | 4 | publish_to: 'none' 5 | 6 | environment: 7 | sdk: ">=2.16.2 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | locale_plus: 14 | path: ../ 15 | 16 | cupertino_icons: ^1.0.2 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | flutter_lints: ^1.0.4 22 | 23 | flutter: 24 | uses-material-design: true 25 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - locale_plus (1.0.1): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `Flutter`) 8 | - locale_plus (from `.symlinks/plugins/locale_plus/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: Flutter 13 | locale_plus: 14 | :path: ".symlinks/plugins/locale_plus/ios" 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 18 | locale_plus: ed29e4100d650f84061473f1b9c6178a920da4c5 19 | 20 | PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011 21 | 22 | COCOAPODS: 1.16.2 23 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/ephemeral/ 38 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /example/android/build.gradle.kts: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() 9 | rootProject.layout.buildDirectory.value(newBuildDir) 10 | 11 | subprojects { 12 | val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) 13 | project.layout.buildDirectory.value(newSubprojectBuildDir) 14 | } 15 | subprojects { 16 | project.evaluationDependsOn(":app") 17 | } 18 | 19 | tasks.register("clean") { 20 | delete(rootProject.layout.buildDirectory) 21 | } 22 | -------------------------------------------------------------------------------- /ios/Classes/LocalePlusPlugin.m: -------------------------------------------------------------------------------- 1 | #import "LocalePlusPlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "locale_plus-Swift.h" 9 | #endif 10 | 11 | @implementation LocalePlusPlugin 12 | + (void)registerWithRegistrar:(NSObject*)registrar { 13 | [SwiftLocalePlusPlugin registerWithRegistrar:registrar]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /ios/Classes/MethodNames.swift: -------------------------------------------------------------------------------- 1 | enum MethodNames: String { 2 | case getGroupingSeparator = "getGroupingSeparator" 3 | case getDecimalSeparator = "getDecimalSeparator" 4 | case getSecondsFromGMT = "getSecondsFromGMT" 5 | case getRegionCode = "getRegionCode" 6 | case getLanguageCode = "getLanguageCode" 7 | case usesMetricSystem = "usesMetricSystem" 8 | case is24HourTime = "is24HourTime" 9 | case getAmSymbol = "getAmSymbol" 10 | case getPmSymbol = "getPmSymbol" 11 | case getTimeZoneIdentifier = "getTimeZoneIdentifier" 12 | case getFirstDayOfWeek = "getFirstDayOfWeek" 13 | case getDateFormatPattern = "getDateFormatPattern" 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | .packages 30 | build/ 31 | .vscode/ 32 | .fvm/ 33 | .fvmrc -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.gokberkbar.locale_plus' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:7.1.2' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | mavenCentral() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | namespace "com.gokberkbar.locale_plus" 26 | compileSdkVersion 31 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_8 30 | targetCompatibility JavaVersion.VERSION_1_8 31 | } 32 | 33 | defaultConfig { 34 | minSdkVersion 16 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: locale_plus 2 | description: LocalePlus allows easy access to native device locale data in Flutter apps. Includes language, country code, time zone, and number formatting preferences. 3 | version: 1.8.0 4 | repository: https://github.com/gokberkbar/locale_plus 5 | 6 | environment: 7 | sdk: ">=3.0.0 <4.0.0" 8 | flutter: ">=3.10.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | intl: ">=0.19.0 <0.21.0" 14 | plugin_platform_interface: ^2.0.2 15 | universal_io: ^2.0.4 16 | 17 | dev_dependencies: 18 | flutter_test: 19 | sdk: flutter 20 | flutter_lints: ^1.0.4 21 | 22 | flutter: 23 | plugin: 24 | platforms: 25 | android: 26 | package: com.gokberkbar.locale_plus 27 | pluginClass: LocalePlusPlugin 28 | ios: 29 | pluginClass: LocalePlusPlugin 30 | -------------------------------------------------------------------------------- /example/android/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | val flutterSdkPath = run { 3 | val properties = java.util.Properties() 4 | file("local.properties").inputStream().use { properties.load(it) } 5 | val flutterSdkPath = properties.getProperty("flutter.sdk") 6 | require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } 7 | flutterSdkPath 8 | } 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id("dev.flutter.flutter-plugin-loader") version "1.0.0" 21 | id("com.android.application") version "8.7.3" apply false 22 | id("org.jetbrains.kotlin.android") version "2.1.0" apply false 23 | } 24 | 25 | include(":app") 26 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .build/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | .swiftpm/ 13 | migrate_working_dir/ 14 | 15 | # IntelliJ related 16 | *.iml 17 | *.ipr 18 | *.iws 19 | .idea/ 20 | 21 | # The .vscode folder contains launch configuration and tasks you configure in 22 | # VS Code which you may wish to be included in version control, so this line 23 | # is commented out by default. 24 | #.vscode/ 25 | 26 | # Flutter/Dart/Pub related 27 | **/doc/api/ 28 | **/ios/Flutter/.last_build_id 29 | .dart_tool/ 30 | .flutter-plugins 31 | .flutter-plugins-dependencies 32 | .packages 33 | .pub-cache/ 34 | .pub/ 35 | /build/ 36 | 37 | # Web related 38 | lib/generated_plugin_registrant.dart 39 | 40 | # Symbolication related 41 | app.*.symbols 42 | 43 | # Obfuscation related 44 | app.*.map.json 45 | 46 | # Android Studio will place build artifacts here 47 | /android/app/debug 48 | /android/app/profile 49 | /android/app/release 50 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Gökberk Bardakçı 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: f1875d570e39de09040c8f79aa13cc56baab8db1 8 | channel: unknown 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 17 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 18 | - platform: android 19 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 20 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 21 | - platform: ios 22 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 23 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /android/src/main/java/com/gokberkbar/locale_plus/MethodNames.java: -------------------------------------------------------------------------------- 1 | package com.gokberkbar.locale_plus; 2 | 3 | public enum MethodNames { 4 | getGroupingSeparator("getGroupingSeparator"), 5 | getDecimalSeparator("getDecimalSeparator"), 6 | getSecondsFromGMT("getSecondsFromGMT"), 7 | getRegionCode("getRegionCode"), 8 | getLanguageCode("getLanguageCode"), 9 | usesMetricSystem("usesMetricSystem"), 10 | is24HourTime("is24HourTime"), 11 | getAmSymbol("getAmSymbol"), 12 | getPmSymbol("getPmSymbol"), 13 | getTimeZoneIdentifier("getTimeZoneIdentifier"), 14 | isUsingSamsungKeyboard("isUsingSamsungKeyboard"), 15 | getFirstDayOfWeek("getFirstDayOfWeek"), 16 | getDateFormatPattern("getDateFormatPattern"); 17 | 18 | private final String text; 19 | 20 | MethodNames(String text) { 21 | this.text = text; 22 | } 23 | 24 | public String getText() { 25 | return this.text; 26 | } 27 | 28 | public static MethodNames fromString(String text) { 29 | for (MethodNames b : MethodNames.values()) { 30 | if (b.text.equalsIgnoreCase(text)) { 31 | return b; 32 | } 33 | } 34 | return null; 35 | } 36 | } -------------------------------------------------------------------------------- /ios/locale_plus.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint locale_plus.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'locale_plus' 7 | s.version = '1.0.1' 8 | s.summary = 'LocalePlus allows easy access to native device locale data in Flutter apps.' 9 | s.description = <<-DESC 10 | LocalePlus allows easy access to native device locale data in Flutter apps. Includes language, country code, time zone, and number formatting preferences. 11 | DESC 12 | s.homepage = 'https://github.com/gokberkbar/locale_plus' 13 | s.license = { :type => 'MIT', :file => '../LICENSE' } 14 | s.author = { 'gokberkbar' => 'gokberkbar@gmail.com', 15 | 'Uygar' => 'uygarisicelik@gmail.com' } 16 | s.source = { :path => '.' } 17 | s.source_files = 'Classes/**/*' 18 | s.dependency 'Flutter' 19 | s.platform = :ios, '9.0' 20 | 21 | # Flutter.framework does not contain a i386 slice. 22 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 23 | s.swift_version = '5.0' 24 | end 25 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /example/android/app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("kotlin-android") 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id("dev.flutter.flutter-gradle-plugin") 6 | } 7 | 8 | android { 9 | namespace = "com.example.locale_plus_example" 10 | compileSdk = flutter.compileSdkVersion 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_11 15 | targetCompatibility = JavaVersion.VERSION_11 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_11.toString() 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "com.example.locale_plus_example" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = flutter.minSdkVersion 28 | targetSdk = flutter.targetSdkVersion 29 | versionCode = flutter.versionCode 30 | versionName = flutter.versionName 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig = signingConfigs.getByName("debug") 38 | } 39 | } 40 | } 41 | 42 | flutter { 43 | source = "../.." 44 | } 45 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "be698c48a6750c8cb8e61c740ca9991bb947aba2" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 17 | base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 18 | - platform: android 19 | create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 20 | base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 21 | - platform: ios 22 | create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 23 | base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 24 | - platform: linux 25 | create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 26 | base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 27 | - platform: macos 28 | create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 29 | base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 30 | - platform: web 31 | create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 32 | base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 33 | - platform: windows 34 | create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 35 | base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Locale Plus 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | locale_plus_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.8.0 2 | 3 | - Add the `getDateFormatPattern` function to getting the default date format pattern from a current locale on Android or from "Language & Region" settings on iOS. 4 | 5 | # 1.7.0 6 | 7 | - remove unused analysis options (#17) 8 | - Relaxed [intl](https://pub.dev/packages/intl) package dependency for flutter version updates. Changed intl dependency version to ">=0.19.0 <0.21.0". 9 | - Fix android warning: [deprecation] locale in Configuration has been deprecated 10 | 11 | # 1.6.0+1 12 | 13 | - README updated. 14 | 15 | # 1.6.0 16 | 17 | - Upgrade Dart SDK version from `2.16.2` to `3.0.0`. 18 | - Upgrade Flutter SDK version from `2.5.0` to `3.10.o`. 19 | - Update [intl](https://pub.dev/packages/intl) package from `0.18.0` to `0.19.0`. 20 | 21 | # 1.5.0 22 | 23 | - "namespace" added to build.gradle file. 24 | - android package name changed. 25 | 26 | # 1.4.1 27 | 28 | - Enhanced the `isUsingSamsungKeyboard` native check to improve the Samsung keyboards recognition. 29 | 30 | # 1.4.0 31 | 32 | - Add the `getFirstDayOfWeek` function to getting the first day of week from a current locale on Android or from "Language & Region" settings on iOS. 33 | 34 | # 1.3.1 35 | 36 | - Update dependencies 37 | 38 | # 1.3.0 39 | 40 | - Add an additional check to make sure the decimal seperator and the group seperator are different. 41 | - Remove the flags from `patchNumberSeperators` that would allow for seperate patching of the group and decimal seperator. 42 | - remove the `shouldPatchLocales` flag from the `patchNumberSeperators`. 43 | 44 | # 1.2.0 45 | 46 | - Add the `isUsingSamsungKeyboard` function to detect if the user is using a samsung keyboard 47 | - Add the `patchForSamsungKeyboards` argument to the `patchNumberSeperators` function, to chan 48 | 49 | # 1.1.1 50 | 51 | - Improve error reporting to the developer 52 | 53 | # 1.1.0 54 | 55 | - Add the `patchNumberSeperators` function to change decimal and group seperators on all locales. 56 | - Get TimeZone Identifier feature implemented. 57 | 58 | # 1.0.1 59 | 60 | Authors updated. 61 | 62 | # 1.0.0 63 | 64 | Initial version release. 65 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/locale_plus_platform_interface.dart: -------------------------------------------------------------------------------- 1 | import 'package:locale_plus/locale_plus.dart'; 2 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 3 | 4 | import 'locale_plus_method_channel.dart'; 5 | 6 | abstract class LocalePlusPlatform extends PlatformInterface { 7 | LocalePlusPlatform() : super(token: _token); 8 | 9 | static final Object _token = Object(); 10 | 11 | static LocalePlusPlatform _instance = MethodChannelLocalePlus(); 12 | 13 | static LocalePlusPlatform get instance => _instance; 14 | 15 | static set instance(LocalePlusPlatform instance) { 16 | PlatformInterface.verifyToken(instance, _token); 17 | _instance = instance; 18 | } 19 | 20 | Future isUsingSamsungKeyboard() => throw UnimplementedError( 21 | 'getDecimalSeparator() has not been implemented on $os.'); 22 | 23 | Future getDecimalSeparator() => throw UnimplementedError( 24 | 'getDecimalSeparator() has not been implemented on $os.'); 25 | 26 | Future getGroupingSeparator() => throw UnimplementedError( 27 | 'getGroupingSeparator() has not been implemented on $os.'); 28 | 29 | Future getSecondsFromGMT() => throw UnimplementedError( 30 | 'getSecondsFromGMT() has not been implemented on $os.'); 31 | 32 | Future getRegionCode() => throw UnimplementedError( 33 | 'getRegionCode() has not been implemented on $os.'); 34 | 35 | Future getLanguageCode() { 36 | throw UnimplementedError( 37 | 'getLanguageCode() has not been implemented on $os.'); 38 | } 39 | 40 | Future usesMetricSystem() => throw UnimplementedError( 41 | 'usesMetricSystem() has not been implemented on $os.'); 42 | 43 | Future is24HourTime() => throw UnimplementedError( 44 | 'is24HourTime() has not been implemented on $os.'); 45 | 46 | Future getAmSymbol() => throw UnimplementedError( 47 | 'getAmSymbol() has not been implemented on $os.'); 48 | 49 | Future getPmSymbol() => throw UnimplementedError( 50 | 'getPmSymbol() has not been implemented on $os.'); 51 | 52 | Future getTimeZoneIdentifier() => throw UnimplementedError( 53 | 'getTimeZoneIdentifier() has not been implemented on $os.'); 54 | 55 | Future getFirstDayOfWeek() => throw UnimplementedError( 56 | 'getFirstDayOfWeek() has not been implemented on $os.'); 57 | 58 | Future getDateFormatPattern() => throw UnimplementedError( 59 | 'getDateFormatPattern() has not been implemented on $os.'); 60 | } 61 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/locale_plus.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/foundation.dart' show kIsWeb; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:universal_io/io.dart'; 6 | 7 | import 'locale_plus_platform_interface.dart'; 8 | 9 | export 'patch_all_locales.dart' show PatchAllLocales; 10 | 11 | @protected 12 | final os = kIsWeb ? 'the browser' : Platform.operatingSystem; 13 | 14 | /// Locale plus is an easy way to get native devices Locale data. 15 | class LocalePlus { 16 | /// Returns the decimal separator for the current locale of device. 17 | Future getDecimalSeparator() { 18 | return LocalePlusPlatform.instance.getDecimalSeparator(); 19 | } 20 | 21 | ///Returns true if the user is using a samsung keyboard. false otherwise. 22 | Future isUsingSamsungKeyboard() => 23 | LocalePlusPlatform.instance.isUsingSamsungKeyboard(); 24 | 25 | /// Returns the grouping separator for the current locale of device. 26 | Future getGroupingSeparator() { 27 | return LocalePlusPlatform.instance.getGroupingSeparator(); 28 | } 29 | 30 | /// Returns the seconds from GMT for the current locale of device. 31 | Future getSecondsFromGMT() { 32 | return LocalePlusPlatform.instance.getSecondsFromGMT(); 33 | } 34 | 35 | /// Returns the region code for the current locale of device. 36 | Future getRegionCode() { 37 | return LocalePlusPlatform.instance.getRegionCode(); 38 | } 39 | 40 | /// Returns the language code for the current locale of device. 41 | Future getLanguageCode() { 42 | return LocalePlusPlatform.instance.getLanguageCode(); 43 | } 44 | 45 | /// Returns true if the device uses Metric System. 46 | Future usesMetricSystem() { 47 | return LocalePlusPlatform.instance.usesMetricSystem(); 48 | } 49 | 50 | /// Returns true if the device uses 24 hour time. 51 | Future is24HourTime() { 52 | return LocalePlusPlatform.instance.is24HourTime(); 53 | } 54 | 55 | /// Returns the AM symbol for the current locale of device. 56 | Future getAmSymbol() { 57 | return LocalePlusPlatform.instance.getAmSymbol(); 58 | } 59 | 60 | /// Returns the PM symbol for the current locale of device. 61 | Future getPmSymbol() { 62 | return LocalePlusPlatform.instance.getPmSymbol(); 63 | } 64 | 65 | /// Returns the time zone identifier for the current locale of device. 66 | Future getTimeZoneIdentifier() { 67 | return LocalePlusPlatform.instance.getTimeZoneIdentifier(); 68 | } 69 | 70 | /// Returns the first day of week for the current locale of device. 71 | /// The values are numbered following the ISO-8601 standard, 72 | /// from 1 (Monday) to 7 (Sunday). 73 | Future getFirstDayOfWeek() { 74 | return LocalePlusPlatform.instance.getFirstDayOfWeek(); 75 | } 76 | 77 | /// Returns the date format pattern for the current locale of device. 78 | Future getDateFormatPattern() { 79 | return LocalePlusPlatform.instance.getDateFormatPattern(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/locale_plus_method_channel.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/services.dart'; 4 | 5 | import 'locale_plus_platform_interface.dart'; 6 | 7 | class MethodChannelLocalePlus extends LocalePlusPlatform { 8 | final methodChannel = const MethodChannel('locale_plus'); 9 | 10 | @override 11 | Future getDecimalSeparator() async { 12 | final decimalSeparator = 13 | await methodChannel.invokeMethod('getDecimalSeparator'); 14 | return decimalSeparator; 15 | } 16 | 17 | @override 18 | Future isUsingSamsungKeyboard() async { 19 | if (Platform.isAndroid) { 20 | return await methodChannel.invokeMethod('isUsingSamsungKeyboard'); 21 | } 22 | return false; 23 | } 24 | 25 | @override 26 | Future getGroupingSeparator() async { 27 | final groupingSeparator = 28 | await methodChannel.invokeMethod('getGroupingSeparator'); 29 | return groupingSeparator; 30 | } 31 | 32 | @override 33 | Future getSecondsFromGMT() async { 34 | final secondsFromGMT = 35 | await methodChannel.invokeMethod('getSecondsFromGMT'); 36 | return secondsFromGMT; 37 | } 38 | 39 | @override 40 | Future getRegionCode() async { 41 | final regionCode = 42 | await methodChannel.invokeMethod('getRegionCode'); 43 | return regionCode; 44 | } 45 | 46 | @override 47 | Future getLanguageCode() async { 48 | final languageCode = 49 | await methodChannel.invokeMethod('getLanguageCode'); 50 | return languageCode; 51 | } 52 | 53 | @override 54 | Future usesMetricSystem() async { 55 | final usesMetricSystem = 56 | await methodChannel.invokeMethod('usesMetricSystem'); 57 | return usesMetricSystem; 58 | } 59 | 60 | @override 61 | Future is24HourTime() async { 62 | final is24HourTime = await methodChannel.invokeMethod('is24HourTime'); 63 | return is24HourTime; 64 | } 65 | 66 | @override 67 | Future getAmSymbol() async { 68 | final amSymbol = await methodChannel.invokeMethod('getAmSymbol'); 69 | return amSymbol; 70 | } 71 | 72 | @override 73 | Future getPmSymbol() async { 74 | final pmSymbol = await methodChannel.invokeMethod('getPmSymbol'); 75 | return pmSymbol; 76 | } 77 | 78 | @override 79 | Future getTimeZoneIdentifier() async { 80 | final timeZoneIdentifier = 81 | await methodChannel.invokeMethod('getTimeZoneIdentifier'); 82 | return timeZoneIdentifier; 83 | } 84 | 85 | @override 86 | Future getFirstDayOfWeek() async { 87 | final firstDayOfWeek = 88 | await methodChannel.invokeMethod('getFirstDayOfWeek'); 89 | return firstDayOfWeek; 90 | } 91 | 92 | @override 93 | Future getDateFormatPattern() async { 94 | final dateFormatPattern = 95 | await methodChannel.invokeMethod('getDateFormatPattern'); 96 | return dateFormatPattern; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/patch_all_locales.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:intl/number_symbols.dart'; 4 | import 'package:intl/number_symbols_data.dart'; 5 | import 'package:locale_plus/locale_plus.dart'; 6 | 7 | extension on NumberSymbols { 8 | NumberSymbols overrideSeperators({ 9 | String? decimalSeparator, 10 | String? groupingSeparator, 11 | }) => 12 | NumberSymbols( 13 | NAME: NAME, 14 | DECIMAL_SEP: decimalSeparator ?? DECIMAL_SEP, 15 | GROUP_SEP: groupingSeparator ?? GROUP_SEP, 16 | PERCENT: PERCENT, 17 | ZERO_DIGIT: ZERO_DIGIT, 18 | PLUS_SIGN: PLUS_SIGN, 19 | MINUS_SIGN: MINUS_SIGN, 20 | EXP_SYMBOL: EXP_SYMBOL, 21 | PERMILL: PERMILL, 22 | INFINITY: INFINITY, 23 | NAN: NAN, 24 | DECIMAL_PATTERN: DECIMAL_PATTERN, 25 | SCIENTIFIC_PATTERN: SCIENTIFIC_PATTERN, 26 | PERCENT_PATTERN: PERCENT_PATTERN, 27 | CURRENCY_PATTERN: CURRENCY_PATTERN, 28 | DEF_CURRENCY_CODE: DEF_CURRENCY_CODE, 29 | ); 30 | } 31 | 32 | // ignore: avoid_classes_with_only_static_members 33 | ///The [PatchAllLocales] exposes async functions 34 | ///to patch the locales in [numberFormatSymbols]. 35 | class PatchAllLocales { 36 | /// [patchNumberSeperators] patches all locales with the 37 | /// decimal seperators to the decimal separator of the user. 38 | /// The locales can also be patched for users with a samsung keyboard. 39 | /// This is done by changing the [patchForSamsungKeyboards] to true. 40 | /// The samsung keyboard always uses a '.' as input for a decimal seperator. 41 | /// This means that the [DECIMAL_SEP] is a '.' and the [GROUP_SEP] is a ',' 42 | /// see https://github.com/flutter/flutter/issues/61175 43 | static Future patchNumberSeperators({ 44 | bool patchForSamsungKeyboards = false, 45 | }) async { 46 | final localePlus = LocalePlus(); 47 | try { 48 | final bool isUsingSamsungKeyboard = patchForSamsungKeyboards && 49 | (await localePlus.isUsingSamsungKeyboard() ?? false); 50 | 51 | final String? userDecimalSeperator = 52 | isUsingSamsungKeyboard ? '.' : await localePlus.getDecimalSeparator(); 53 | 54 | final String? userGroupingSeperator = isUsingSamsungKeyboard 55 | ? ',' 56 | : await localePlus.getGroupingSeparator(); 57 | 58 | if (userDecimalSeperator == null || userGroupingSeperator == null) { 59 | return debugPrint(''' 60 | The decimalSeperator and/or groupingSeperator can not be found. 61 | The locales are not patched. 62 | '''); 63 | } 64 | if (userDecimalSeperator == userGroupingSeperator) { 65 | return debugPrint(''' 66 | locale_plus: The group seperator and decimalSeperator are the same. 67 | the locales are not patched. 68 | decimal seperator: $userDecimalSeperator 69 | group seperator: $userGroupingSeperator 70 | '''); 71 | } 72 | final entries = numberFormatSymbols.entries 73 | as Iterable>; 74 | for (final MapEntry n in entries) { 75 | numberFormatSymbols[n.key] = n.value.overrideSeperators( 76 | decimalSeparator: userDecimalSeperator, 77 | groupingSeparator: userGroupingSeperator, 78 | ); 79 | } 80 | } on MissingPluginException { 81 | debugPrint( 82 | '''locale_plus: plugin is not implemented on $os. The locales are not patched.'''); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 38 | 39 | 40 | 41 | 42 | 43 | 55 | 57 | 63 | 64 | 65 | 66 | 72 | 74 | 80 | 81 | 82 | 83 | 85 | 86 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /ios/Classes/SwiftLocalePlusPlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | public class SwiftLocalePlusPlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | let channel = FlutterMethodChannel(name: "locale_plus", binaryMessenger: registrar.messenger()) 7 | let instance = SwiftLocalePlusPlugin() 8 | registrar.addMethodCallDelegate(instance, channel: channel) 9 | } 10 | 11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 12 | switch call.method { 13 | case MethodNames.getDecimalSeparator.rawValue: 14 | result(Locale.autoupdatingCurrent.decimalSeparator) 15 | case MethodNames.getGroupingSeparator.rawValue: 16 | result(Locale.autoupdatingCurrent.groupingSeparator) 17 | case MethodNames.getSecondsFromGMT.rawValue: 18 | result(TimeZone.autoupdatingCurrent.secondsFromGMT()) 19 | case MethodNames.getRegionCode.rawValue: 20 | result(Locale.autoupdatingCurrent.regionCode) 21 | case MethodNames.getLanguageCode.rawValue: 22 | result(getPrefferedLanguageLocale().languageCode) 23 | case MethodNames.usesMetricSystem.rawValue: 24 | result(usesMetricSystem()) 25 | case MethodNames.is24HourTime.rawValue: 26 | result(is24HourTime()) 27 | case MethodNames.getAmSymbol.rawValue: 28 | result(getPrefferedLanguageLocale().calendar.amSymbol) 29 | case MethodNames.getPmSymbol.rawValue: 30 | result(getPrefferedLanguageLocale().calendar.pmSymbol) 31 | case MethodNames.getTimeZoneIdentifier.rawValue: 32 | result(TimeZone.autoupdatingCurrent.identifier) 33 | case MethodNames.getFirstDayOfWeek.rawValue: 34 | result(getFirstDayOfWeek()) 35 | case MethodNames.getDateFormatPattern.rawValue: 36 | result(getDateFormatPattern()) 37 | default: 38 | return 39 | } 40 | } 41 | 42 | private func is24HourTime() -> Bool { 43 | let formatter : String = DateFormatter.dateFormat(fromTemplate: "j", options:0, locale:Locale.autoupdatingCurrent)! 44 | if formatter.contains("a") { 45 | return false 46 | } else { 47 | return true 48 | } 49 | } 50 | 51 | private func usesMetricSystem() -> Bool { 52 | if #available(iOS 16, *) { 53 | return Locale.autoupdatingCurrent.measurementSystem == Locale.MeasurementSystem.metric 54 | } else { 55 | return Locale.autoupdatingCurrent.usesMetricSystem 56 | } 57 | } 58 | 59 | private func getFirstDayOfWeek() -> Int { 60 | let firstDay = Calendar.current.firstWeekday; 61 | if (firstDay == 1) { 62 | return 7; 63 | } else { 64 | return firstDay - 1; 65 | } 66 | } 67 | 68 | private func getPrefferedLanguageLocale() -> Locale { 69 | guard let prefferedLanguage = Locale.preferredLanguages.first else { 70 | return Locale.current 71 | } 72 | return Locale(identifier: prefferedLanguage) 73 | } 74 | 75 | private func getDateFormatPattern() -> String { 76 | let formatter = DateFormatter() 77 | formatter.locale = Locale.autoupdatingCurrent 78 | formatter.dateStyle = .short 79 | formatter.timeStyle = .none 80 | 81 | let calendar = Calendar(identifier: .gregorian) 82 | let components = DateComponents(calendar: calendar, year: 2025, month: 7, day: 4) 83 | guard let testDate = components.date else { 84 | return "MM/dd/yyyy" // fallback 85 | } 86 | 87 | let formatted = formatter.string(from: testDate) 88 | // e.g., "7/4/25" or "04.07.2025" or "2025-07-04" 89 | 90 | var pattern = formatted 91 | 92 | // Replace known values with tokens 93 | pattern = pattern.replacingOccurrences(of: "2025", with: "yyyy") 94 | pattern = pattern.replacingOccurrences(of: "25", with: "yy") // fallback if short year is used 95 | pattern = pattern.replacingOccurrences(of: "07", with: "MM") 96 | pattern = pattern.replacingOccurrences(of: "7", with: "M") 97 | pattern = pattern.replacingOccurrences(of: "04", with: "dd") 98 | pattern = pattern.replacingOccurrences(of: "4", with: "d") 99 | 100 | return pattern 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:locale_plus/locale_plus.dart'; 5 | 6 | Future main() async { 7 | WidgetsFlutterBinding.ensureInitialized(); 8 | await PatchAllLocales.patchNumberSeperators( 9 | patchForSamsungKeyboards: true, 10 | ); 11 | runApp(const MyApp()); 12 | } 13 | 14 | class MyApp extends StatefulWidget { 15 | const MyApp({Key? key}) : super(key: key); 16 | 17 | @override 18 | State createState() => _MyAppState(); 19 | } 20 | 21 | class _MyAppState extends State { 22 | String? decimalSeparator; 23 | String? groupingSeparator; 24 | bool? isUsingSamsungKeyboard; 25 | int? secondsFromGMT; 26 | String? regionCode; 27 | String? languageCode; 28 | bool? usesMetricSystem; 29 | bool? is24HourTime; 30 | String? amSymbol; 31 | String? pmSymbol; 32 | String? timeZoneIdentifier; 33 | int? firstDayOfWeek; 34 | String? dateFormatPattern; 35 | @override 36 | void initState() { 37 | super.initState(); 38 | initPlatformState(); 39 | } 40 | 41 | Future initPlatformState() async { 42 | decimalSeparator = await LocalePlus().getDecimalSeparator(); 43 | groupingSeparator = await LocalePlus().getGroupingSeparator(); 44 | isUsingSamsungKeyboard = await LocalePlus().isUsingSamsungKeyboard(); 45 | secondsFromGMT = await LocalePlus().getSecondsFromGMT(); 46 | regionCode = await LocalePlus().getRegionCode(); 47 | languageCode = await LocalePlus().getLanguageCode(); 48 | usesMetricSystem = await LocalePlus().usesMetricSystem(); 49 | is24HourTime = await LocalePlus().is24HourTime(); 50 | amSymbol = await LocalePlus().getAmSymbol(); 51 | pmSymbol = await LocalePlus().getPmSymbol(); 52 | timeZoneIdentifier = await LocalePlus().getTimeZoneIdentifier(); 53 | firstDayOfWeek = await LocalePlus().getFirstDayOfWeek(); 54 | dateFormatPattern = await LocalePlus().getDateFormatPattern(); 55 | setState(() {}); 56 | } 57 | 58 | @override 59 | Widget build(BuildContext context) { 60 | return MaterialApp( 61 | home: Scaffold( 62 | appBar: AppBar( 63 | title: const Text('Plugin example app'), 64 | ), 65 | body: Center( 66 | child: Column( 67 | crossAxisAlignment: CrossAxisAlignment.stretch, 68 | children: [ 69 | Text( 70 | 'Decimal Separator: $decimalSeparator', 71 | textAlign: TextAlign.center, 72 | ), 73 | Text( 74 | 'Grouping Separator: $groupingSeparator', 75 | textAlign: TextAlign.center, 76 | ), 77 | Text( 78 | 'is using samsung keyboard: $isUsingSamsungKeyboard', 79 | textAlign: TextAlign.center, 80 | ), 81 | Text( 82 | 'Seconds From GMT: $secondsFromGMT', 83 | textAlign: TextAlign.center, 84 | ), 85 | Text( 86 | 'Region Code: $regionCode', 87 | textAlign: TextAlign.center, 88 | ), 89 | Text( 90 | 'Language Code: $languageCode', 91 | textAlign: TextAlign.center, 92 | ), 93 | Text( 94 | 'Uses Metric System: $usesMetricSystem', 95 | textAlign: TextAlign.center, 96 | ), 97 | Text( 98 | 'Is 24 Hour Time: $is24HourTime', 99 | textAlign: TextAlign.center, 100 | ), 101 | Text( 102 | 'AM Symbol: $amSymbol', 103 | textAlign: TextAlign.center, 104 | ), 105 | Text( 106 | 'PM Symbol: $pmSymbol', 107 | textAlign: TextAlign.center, 108 | ), 109 | Text( 110 | 'Time Zone Identifier: $timeZoneIdentifier', 111 | textAlign: TextAlign.center, 112 | ), 113 | Text( 114 | 'First day of week: $firstDayOfWeek', 115 | textAlign: TextAlign.center, 116 | ), 117 | Text( 118 | 'Date Format Pattern: $dateFormatPattern', 119 | textAlign: TextAlign.center, 120 | ), 121 | ], 122 | ), 123 | ), 124 | ), 125 | ); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Locale Plus 2 | 3 | LocalePlus allows easy access to native device locale data in Flutter apps. Includes language, country code, time zone, and number formatting preferences. 4 | 5 | # Table of Content 6 | 7 | - [Overview](#overview) 8 | - [Requirements](#requirements) 9 | - [Installation](#installation) 10 | - [Usage](#usage) 11 | - [Author](#author) 12 | - [Contributors](#contributors) 13 | - [LICENSE](#license) 14 | 15 | # Overview 16 | 17 | LocalePlus is a Flutter package that allows developers to easily retrieve data from the native device locale settings. With LocalePlus, developers can access information such as the device's language, country code, and time zone, as well as the device's number formatting preferences such as grouping and decimal separator. This makes it easy to build internationalized apps that provide a personalized experience for each user. Whether you're building a financial app that needs to display numbers in the user's local format or a social media app that needs to display timestamps in the user's time zone, LocalePlus has you covered. With a simple and intuitive API, LocalePlus is the perfect tool for any Flutter developer looking to add localization to their app. 18 | 19 | # Requirements 20 | 21 | - Dart sdk: ">=3.0.0 <4.0.0" 22 | - Flutter: ">=3.10.0" 23 | - Android: minSdkVersion 16 24 | - iOS 9.0+ 25 | 26 | # Installation 27 | 28 | with Flutter: 29 | 30 | ``` 31 | $ flutter pub add locale_plus 32 | ``` 33 | 34 | This will add a line like this to your package's pubspec.yaml (and run an implicit `flutter pub get`): 35 | 36 | ``` 37 | dependencies: 38 | locale_plus: ^1.8.0 39 | ``` 40 | 41 | # Usage 42 | 43 | ## Patch the locales with the users' group and decimal seperators 44 | 45 | This function patches all locales in flutter, so that you can use the decimal seperator and group seperator from `numberFormatSymbols` after the patch is complete. 46 | The patchNumberSeperators function patches the locales on android and ios. 47 | The `shouldPatchForSamsungKeyboard` can be enabled, to patch for Samsung keyboards on android phones (they only allow for a `.` as input). 48 | It is safe to call on MacOS, Windows, Linux and web, but it does not patch the locales. 49 | 50 | ```Dart 51 | import 'package:locale_plus/locale_plus.dart'; 52 | 53 | Future main() async { 54 | WidgetsFlutterBinding.ensureInitialized(); 55 | await PatchAllLocales.patchNumberSeperators( 56 | shouldPatchForSamsungKeyboard: true, 57 | ); 58 | runApp(const MyApp()); 59 | } 60 | ``` 61 | 62 | ## Get if the user is using a samsung keyboard 63 | 64 | ```Dart 65 | final decimalSeparator = await LocalePlus().isUsingSamsungKeyboard(); 66 | ``` 67 | 68 | ## Get Decimal & Grouping Separator 69 | 70 | ```Dart 71 | final decimalSeparator = await LocalePlus().getDecimalSeparator(); 72 | final groupingSeparator = await LocalePlus().getGroupingSeparator(); 73 | ``` 74 | 75 | ## Get Language & Region Code 76 | 77 | ```Dart 78 | final regionCode = await LocalePlus().getRegionCode(); 79 | final languageCode = await LocalePlus().getLanguageCode(); 80 | ``` 81 | 82 | ## Get Seconds from GMT 83 | 84 | ```Dart 85 | final secondsFromGMT = await LocalePlus().getSecondsFromGMT(); 86 | ``` 87 | 88 | ## Is Device Using 24 hour time and Current Locale AM PM Symbols 89 | 90 | ```Dart 91 | final is24HourTime = await LocalePlus().is24HourTime(); 92 | final amSymbol = await LocalePlus().getAmSymbol(); 93 | final pmSymbol = await LocalePlus().getPmSymbol(); 94 | ``` 95 | 96 | ## Is Device Using Metric System 97 | 98 | ```Dart 99 | final usesMetricSystem = await LocalePlus().usesMetricSystem(); 100 | ``` 101 | 102 | ## Get TimeZone Identifier 103 | 104 | ```Dart 105 | final timeZoneIdentifier = await LocalePlus().getTimeZoneIdentifier(); 106 | ``` 107 | 108 | ## Get First Day Of Week 109 | 110 | ```Dart 111 | final firstDayOfWeek = await LocalePlus().getFirstDayOfWeek(); 112 | ``` 113 | 114 | ## Get Date format pattern 115 | 116 | ```Dart 117 | final dateFormatPattern = await LocalePlus().getDateFormatPattern(); 118 | ``` 119 | 120 | # Author 121 | 122 | [Gökberk Bardakçı](https://www.github.com/gokberkbar), [Uygar İşiçelik](https://www.github.com/uygar) 123 | 124 | # Contributors 125 | 126 | [Bent Engbers](https://github.com/BentEngbers), [Renat Shakhmatov](https://github.com/shushper), [Giovanni Lattanzio](https://github.com/giovannilattanziocrispy), [Gökhan Çavuş](https://github.com/gokhancvs) 127 | 128 | # License 129 | 130 | LocalePlus is available under the MIT license. See the LICENSE file for more info. 131 | -------------------------------------------------------------------------------- /android/src/main/java/com/gokberkbar/locale_plus/LocalePlusPlugin.java: -------------------------------------------------------------------------------- 1 | package com.gokberkbar.locale_plus; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.provider.Settings; 6 | import android.text.format.DateFormat; 7 | import android.view.inputmethod.InputMethodManager; 8 | import android.content.res.Configuration; 9 | 10 | import androidx.annotation.NonNull; 11 | 12 | import java.text.DateFormatSymbols; 13 | import java.text.DecimalFormatSymbols; 14 | import java.time.temporal.WeekFields; 15 | import java.util.Calendar; 16 | import java.util.Date; 17 | import java.util.GregorianCalendar; 18 | import java.util.Locale; 19 | import java.util.TimeZone; 20 | 21 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 22 | import io.flutter.plugin.common.MethodCall; 23 | import io.flutter.plugin.common.MethodChannel; 24 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 25 | import io.flutter.plugin.common.MethodChannel.Result; 26 | 27 | public class LocalePlusPlugin implements FlutterPlugin, MethodCallHandler { 28 | 29 | private MethodChannel channel; 30 | private Context mContext; 31 | 32 | @Override 33 | public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { 34 | mContext = flutterPluginBinding.getApplicationContext(); 35 | channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "locale_plus"); 36 | channel.setMethodCallHandler(this); 37 | } 38 | 39 | private boolean usingKeyboard(@NonNull String keyboardId) { 40 | final InputMethodManager richImm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 41 | String defaultKeyboard = Settings.Secure.getString(mContext.getContentResolver(), 42 | Settings.Secure.DEFAULT_INPUT_METHOD); 43 | if (defaultKeyboard == null) { 44 | return false; 45 | } else { 46 | defaultKeyboard = defaultKeyboard.toLowerCase(); 47 | } 48 | return defaultKeyboard.contains(keyboardId.toLowerCase()); 49 | } 50 | 51 | @Override 52 | public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { 53 | Configuration config = mContext.getResources().getConfiguration(); 54 | Locale currentLocale; 55 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 56 | currentLocale = config.getLocales().get(0); 57 | } else { 58 | currentLocale = config.locale; 59 | } 60 | 61 | if (call.method.equals(MethodNames.getDecimalSeparator.getText())) { 62 | char decimalSeparator = DecimalFormatSymbols.getInstance(currentLocale).getDecimalSeparator(); 63 | result.success(String.valueOf(decimalSeparator)); 64 | } else if (call.method.equals(MethodNames.getGroupingSeparator.getText())) { 65 | char groupingSeparator = DecimalFormatSymbols.getInstance(currentLocale).getGroupingSeparator(); 66 | result.success(String.valueOf(groupingSeparator)); 67 | } else if (call.method.equals(MethodNames.getSecondsFromGMT.getText())) { 68 | int secondsFromGmt = TimeZone.getDefault().getRawOffset() / 1000; 69 | result.success(secondsFromGmt); 70 | } else if (call.method.equals(MethodNames.getRegionCode.getText())) { 71 | String regionCode = currentLocale.getCountry(); 72 | result.success(regionCode); 73 | } else if (call.method.equals(MethodNames.getLanguageCode.getText())) { 74 | String languageCode = currentLocale.getLanguage(); 75 | result.success(languageCode); 76 | } else if (call.method.equals(MethodNames.usesMetricSystem.getText())) { 77 | result.success(usesMetricSystem(currentLocale)); 78 | } else if (call.method.equals(MethodNames.is24HourTime.getText())) { 79 | boolean is24HourTime = DateFormat.is24HourFormat(mContext); 80 | result.success(is24HourTime); 81 | } else if (call.method.equals(MethodNames.getAmSymbol.getText())) { 82 | String[] amPmStrings = DateFormatSymbols.getInstance(currentLocale).getAmPmStrings(); 83 | if (amPmStrings.length > 0) { 84 | result.success(amPmStrings[0]); 85 | } else { 86 | result.success(null); 87 | } 88 | } else if (call.method.equals(MethodNames.getPmSymbol.getText())) { 89 | String[] amPmStrings = DateFormatSymbols.getInstance(currentLocale).getAmPmStrings(); 90 | if (amPmStrings.length > 0) { 91 | result.success(amPmStrings[amPmStrings.length - 1]); 92 | } else { 93 | result.success(null); 94 | } 95 | } else if (call.method.equals(MethodNames.getTimeZoneIdentifier.getText())) { 96 | String timeZoneIdentifier = TimeZone.getDefault().getID(); 97 | result.success(timeZoneIdentifier); 98 | } else if (call.method.equals(MethodNames.isUsingSamsungKeyboard.getText())) { 99 | result.success(usingKeyboard("samsung")); 100 | } else if (call.method.equals(MethodNames.getFirstDayOfWeek.getText())) { 101 | result.success(getFirstDayOfWeek(currentLocale)); 102 | } else if (call.method.equals(MethodNames.getDateFormatPattern.getText())) { 103 | result.success(getDateFormatPattern(currentLocale)); 104 | } else { 105 | result.notImplemented(); 106 | } 107 | } 108 | 109 | private boolean usesMetricSystem(Locale locale) { 110 | String countryCode = locale.getCountry(); 111 | switch (countryCode) { 112 | case "US": 113 | case "LR": 114 | case "MM": 115 | return false; 116 | default: 117 | return true; 118 | } 119 | } 120 | 121 | private int getFirstDayOfWeek(Locale locale) { 122 | if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 123 | WeekFields weekFields = WeekFields.of(locale); 124 | return weekFields.getFirstDayOfWeek().getValue(); 125 | } else { 126 | Calendar cal = Calendar.getInstance(locale); 127 | int firstDayOfWeek = cal.getFirstDayOfWeek(); 128 | if (firstDayOfWeek == 1) { 129 | return 7; 130 | } else { 131 | return firstDayOfWeek - 1; 132 | } 133 | } 134 | } 135 | 136 | private String getDateFormatPattern(Locale locale) { 137 | // Known test date: 4 July 2025 138 | Calendar calendar = new GregorianCalendar(2025, Calendar.JULY, 4); 139 | Date testDate = calendar.getTime(); 140 | 141 | java.text.DateFormat javaDateFormat = DateFormat.getDateFormat(mContext); // user-visible 142 | String formatted = javaDateFormat.format(testDate); // e.g., "4/7/25", "04.07.2025" 143 | 144 | // Rebuild pattern 145 | String pattern = formatted; 146 | pattern = pattern.replace("2025", "yyyy"); 147 | pattern = pattern.replace("25", "yy"); // fallback if only 2-digit year used 148 | pattern = pattern.replace("07", "MM"); 149 | pattern = pattern.replace("7", "M"); 150 | pattern = pattern.replace("04", "dd"); 151 | pattern = pattern.replace("4", "d"); 152 | 153 | return pattern; 154 | } 155 | 156 | @Override 157 | public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { 158 | channel.setMethodCallHandler(null); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.13.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.2" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.4.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.2" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.19.1" 44 | cupertino_icons: 45 | dependency: "direct main" 46 | description: 47 | name: cupertino_icons 48 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.0.5" 52 | fake_async: 53 | dependency: transitive 54 | description: 55 | name: fake_async 56 | sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.3.3" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_lints: 66 | dependency: "direct dev" 67 | description: 68 | name: flutter_lints 69 | sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 70 | url: "https://pub.dev" 71 | source: hosted 72 | version: "1.0.4" 73 | flutter_test: 74 | dependency: "direct dev" 75 | description: flutter 76 | source: sdk 77 | version: "0.0.0" 78 | intl: 79 | dependency: transitive 80 | description: 81 | name: intl 82 | sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "0.19.0" 86 | leak_tracker: 87 | dependency: transitive 88 | description: 89 | name: leak_tracker 90 | sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" 91 | url: "https://pub.dev" 92 | source: hosted 93 | version: "10.0.9" 94 | leak_tracker_flutter_testing: 95 | dependency: transitive 96 | description: 97 | name: leak_tracker_flutter_testing 98 | sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 99 | url: "https://pub.dev" 100 | source: hosted 101 | version: "3.0.9" 102 | leak_tracker_testing: 103 | dependency: transitive 104 | description: 105 | name: leak_tracker_testing 106 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 107 | url: "https://pub.dev" 108 | source: hosted 109 | version: "3.0.1" 110 | lints: 111 | dependency: transitive 112 | description: 113 | name: lints 114 | sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c 115 | url: "https://pub.dev" 116 | source: hosted 117 | version: "1.0.1" 118 | locale_plus: 119 | dependency: "direct main" 120 | description: 121 | path: ".." 122 | relative: true 123 | source: path 124 | version: "1.7.0" 125 | matcher: 126 | dependency: transitive 127 | description: 128 | name: matcher 129 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 130 | url: "https://pub.dev" 131 | source: hosted 132 | version: "0.12.17" 133 | material_color_utilities: 134 | dependency: transitive 135 | description: 136 | name: material_color_utilities 137 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 138 | url: "https://pub.dev" 139 | source: hosted 140 | version: "0.11.1" 141 | meta: 142 | dependency: transitive 143 | description: 144 | name: meta 145 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c 146 | url: "https://pub.dev" 147 | source: hosted 148 | version: "1.16.0" 149 | path: 150 | dependency: transitive 151 | description: 152 | name: path 153 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" 154 | url: "https://pub.dev" 155 | source: hosted 156 | version: "1.9.1" 157 | plugin_platform_interface: 158 | dependency: transitive 159 | description: 160 | name: plugin_platform_interface 161 | sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a 162 | url: "https://pub.dev" 163 | source: hosted 164 | version: "2.1.3" 165 | sky_engine: 166 | dependency: transitive 167 | description: flutter 168 | source: sdk 169 | version: "0.0.0" 170 | source_span: 171 | dependency: transitive 172 | description: 173 | name: source_span 174 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" 175 | url: "https://pub.dev" 176 | source: hosted 177 | version: "1.10.1" 178 | stack_trace: 179 | dependency: transitive 180 | description: 181 | name: stack_trace 182 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" 183 | url: "https://pub.dev" 184 | source: hosted 185 | version: "1.12.1" 186 | stream_channel: 187 | dependency: transitive 188 | description: 189 | name: stream_channel 190 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" 191 | url: "https://pub.dev" 192 | source: hosted 193 | version: "2.1.4" 194 | string_scanner: 195 | dependency: transitive 196 | description: 197 | name: string_scanner 198 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" 199 | url: "https://pub.dev" 200 | source: hosted 201 | version: "1.4.1" 202 | term_glyph: 203 | dependency: transitive 204 | description: 205 | name: term_glyph 206 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" 207 | url: "https://pub.dev" 208 | source: hosted 209 | version: "1.2.2" 210 | test_api: 211 | dependency: transitive 212 | description: 213 | name: test_api 214 | sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd 215 | url: "https://pub.dev" 216 | source: hosted 217 | version: "0.7.4" 218 | typed_data: 219 | dependency: transitive 220 | description: 221 | name: typed_data 222 | sha256: "53bdf7e979cfbf3e28987552fd72f637e63f3c8724c9e56d9246942dc2fa36ee" 223 | url: "https://pub.dev" 224 | source: hosted 225 | version: "1.3.0" 226 | universal_io: 227 | dependency: transitive 228 | description: 229 | name: universal_io 230 | sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d" 231 | url: "https://pub.dev" 232 | source: hosted 233 | version: "2.2.0" 234 | vector_math: 235 | dependency: transitive 236 | description: 237 | name: vector_math 238 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 239 | url: "https://pub.dev" 240 | source: hosted 241 | version: "2.1.4" 242 | vm_service: 243 | dependency: transitive 244 | description: 245 | name: vm_service 246 | sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 247 | url: "https://pub.dev" 248 | source: hosted 249 | version: "15.0.0" 250 | sdks: 251 | dart: ">=3.7.0-0 <4.0.0" 252 | flutter: ">=3.18.0-18.0.pre.54" 253 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | analyzer: 13 | errors: 14 | # treat missing required parameters as an error (not a hint) 15 | missing_required_param: error 16 | # treat missing returns as an error (not a hint) 17 | missing_return: error 18 | prefer_mixin: info 19 | always_declare_return_types: error 20 | avoid_web_libraries_in_flutter: false 21 | 22 | # Reassignment should be treated as warning (not a hint) 23 | parameter_assignments: warning 24 | 25 | # allow having TODOs in code 26 | todo: ignore 27 | 28 | exclude: 29 | # Generated for Flutter web apps. Since it is auto-generated, errors should be ignored 30 | # - lib/**.g.dart 31 | - lib/**/*.g.dart 32 | - build/** 33 | 34 | linter: 35 | rules: 36 | # This list is derived from the list of all available lints located at 37 | # https://github.com/dart-lang/linter/blob/master/example/all.yaml 38 | - always_declare_return_types 39 | - always_put_control_body_on_new_line 40 | - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 41 | # - always_specify_types 42 | # - always_use_package_imports # we do this commonly 43 | - annotate_overrides 44 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types 45 | - avoid_bool_literals_in_conditional_expressions 46 | # - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023 47 | # - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023 48 | - avoid_classes_with_only_static_members 49 | - avoid_double_and_int_checks 50 | # - avoid_dynamic_calls # LOCAL CHANGE - Needs to be enabled and violations fixed. 51 | - avoid_empty_else 52 | - avoid_equals_and_hash_code_on_mutable_classes 53 | - avoid_escaping_inner_quotes 54 | - avoid_field_initializers_in_const_classes 55 | # - avoid_final_parameters # incompatible with prefer_final_parameters 56 | - avoid_function_literals_in_foreach_calls 57 | # - avoid_implementing_value_types # LOCAL CHANGE - Needs to be enabled and violations fixed. 58 | - avoid_init_to_null 59 | - avoid_js_rounded_ints 60 | # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to 61 | - avoid_null_checks_in_equality_operators 62 | # - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it 63 | # - avoid_print # LOCAL CHANGE - Needs to be enabled and violations fixed. 64 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 65 | - avoid_redundant_argument_values 66 | # - avoid_relative_lib_imports 67 | - avoid_renaming_method_parameters 68 | - avoid_return_types_on_setters 69 | # - avoid_returning_null # still violated by some pre-nnbd code that we haven't yet migrated 70 | - avoid_returning_null_for_void 71 | # - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives 72 | - avoid_setters_without_getters 73 | - avoid_shadowing_type_parameters 74 | - avoid_single_cascade_in_expression_statements 75 | - avoid_slow_async_io 76 | - avoid_type_to_string 77 | - avoid_types_as_parameter_names 78 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types 79 | - avoid_unnecessary_containers 80 | - avoid_unused_constructor_parameters 81 | - avoid_void_async 82 | # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere 83 | - await_only_futures 84 | - camel_case_extensions 85 | - camel_case_types 86 | - cancel_subscriptions 87 | # - cascade_invocations # doesn't match the typical style of this repo 88 | - cast_nullable_to_non_nullable 89 | # - close_sinks # not reliable enough 90 | # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 91 | # - conditional_uri_does_not_exist # not yet tested 92 | # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 93 | - control_flow_in_finally 94 | # - curly_braces_in_flow_control_structures # not required by flutter style 95 | # - depend_on_referenced_packages # LOCAL CHANGE - Needs to be enabled and violations fixed. 96 | - deprecated_consistency 97 | # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) 98 | # - directives_ordering 99 | # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic 100 | - empty_catches 101 | - empty_constructor_bodies 102 | - empty_statements 103 | - eol_at_end_of_file 104 | - exhaustive_cases 105 | - file_names 106 | - hash_and_equals 107 | - implementation_imports 108 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 109 | - collection_methods_unrelated_type 110 | # - join_return_with_assignment # not required by flutter style 111 | - leading_newlines_in_multiline_strings 112 | - library_names 113 | - library_prefixes 114 | - library_private_types_in_public_api 115 | - lines_longer_than_80_chars # not required by flutter style 116 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453 117 | # - missing_whitespace_between_adjacent_strings 118 | - no_adjacent_strings_in_list 119 | # - no_default_cases # LOCAL CHANGE - Needs to be enabled and violations fixed. 120 | - no_duplicate_case_values 121 | - no_leading_underscores_for_library_prefixes 122 | - no_leading_underscores_for_local_identifiers # LOCAL CHANGE - Needs to be enabled and violations fixed. 123 | - no_logic_in_create_state 124 | # - no_runtimeType_toString # ok in tests; we enable this only in packages/ 125 | - non_constant_identifier_names 126 | - noop_primitive_operations 127 | - null_check_on_nullable_type_parameter 128 | - null_closures 129 | # - omit_local_variable_types # opposite of always_specify_types 130 | # - one_member_abstracts # too many false positives 131 | # - only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al # LOCAL CHANGE - Needs to be enabled and violations fixed. 132 | - overridden_fields 133 | - package_names 134 | - package_prefixed_library_names 135 | # - parameter_assignments # we do this commonly 136 | - prefer_adjacent_string_concatenation 137 | - prefer_asserts_in_initializer_lists 138 | # - prefer_asserts_with_message # not required by flutter style 139 | - prefer_collection_literals 140 | - prefer_conditional_assignment 141 | - prefer_const_constructors 142 | - prefer_const_constructors_in_immutables 143 | - prefer_const_declarations 144 | - prefer_const_literals_to_create_immutables 145 | # - prefer_constructors_over_static_methods # far too many false positives 146 | - prefer_contains 147 | # - prefer_double_quotes # opposite of prefer_single_quotes 148 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 149 | - prefer_final_fields 150 | - prefer_final_in_for_each 151 | - prefer_final_locals 152 | # - prefer_final_parameters # we should enable this one day when it can be auto-fixed (https://github.com/dart-lang/linter/issues/3104), see also parameter_assignments 153 | - prefer_for_elements_to_map_fromIterable 154 | - prefer_foreach 155 | - prefer_function_declarations_over_variables 156 | - prefer_generic_function_type_aliases 157 | - prefer_if_elements_to_conditional_expressions 158 | - prefer_if_null_operators 159 | - prefer_initializing_formals 160 | - prefer_inlined_adds 161 | # - prefer_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants 162 | - prefer_interpolation_to_compose_strings 163 | - prefer_is_empty 164 | - prefer_is_not_empty 165 | - prefer_is_not_operator 166 | - prefer_iterable_whereType 167 | # - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018 168 | # - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere 169 | - prefer_null_aware_operators 170 | # - prefer_relative_imports # LOCAL CHANGE - Needs to be enabled and violations fixed. 171 | - prefer_single_quotes 172 | - prefer_spread_collections 173 | - prefer_typing_uninitialized_variables 174 | - prefer_void_to_null 175 | - provide_deprecation_message 176 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 177 | - recursive_getters 178 | # - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441 179 | - secure_pubspec_urls 180 | # - sized_box_for_whitespace # LOCAL CHANGE - Needs to be enabled and violations fixed. 181 | # - sized_box_shrink_expand # not yet tested 182 | - slash_for_doc_comments 183 | - sort_child_properties_last 184 | # - sort_constructors_first 185 | # - sort_pub_dependencies # prevents separating pinned transitive dependencies 186 | - sort_unnamed_constructors_first 187 | - test_types_in_equals 188 | - throw_in_finally 189 | - tighten_type_of_initializing_formals 190 | # - type_annotate_public_apis # subset of always_specify_types 191 | - type_init_formals 192 | # - unawaited_futures # too many false positives, especially with the way AnimationController works 193 | # - unnecessary_await_in_return # LOCAL CHANGE - Needs to be enabled and violations fixed. 194 | - unnecessary_brace_in_string_interps 195 | - unnecessary_const 196 | - unnecessary_constructor_name 197 | # - unnecessary_final # conflicts with prefer_final_locals 198 | - unnecessary_getters_setters 199 | # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 200 | - unnecessary_late 201 | - unnecessary_new 202 | - unnecessary_null_aware_assignments 203 | - unnecessary_null_checks 204 | - unnecessary_null_in_if_null_operators 205 | - unnecessary_nullable_for_final_variable_declarations 206 | - unnecessary_overrides 207 | - unnecessary_parenthesis 208 | # - unnecessary_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint 209 | - unnecessary_statements 210 | - unnecessary_string_escapes 211 | - unnecessary_string_interpolations 212 | - unnecessary_this 213 | - unrelated_type_equality_checks 214 | # - use_build_context_synchronously # LOCAL CHANGE - Needs to be enabled and violations fixed. 215 | # - use_colored_box # not yet tested 216 | # - use_decorated_box # not yet tested 217 | # - use_enums # not yet tested 218 | - use_full_hex_values_for_flutter_colors 219 | - use_function_type_syntax_for_parameters 220 | - use_if_null_to_convert_nulls_to_bools 221 | - use_is_even_rather_than_modulo 222 | - use_key_in_widget_constructors 223 | - use_late_for_private_fields_and_variables 224 | - use_named_constants # LOCAL CHANGE - Needs to be enabled and violations fixed. 225 | - use_raw_strings 226 | - use_rethrow_when_possible 227 | - use_setters_to_change_properties 228 | # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 229 | # - use_super_parameters 230 | - use_test_throws_matchers 231 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 232 | - valid_regexps 233 | - void_checks 234 | ### Local flutter/plugins additions ### 235 | # These are from flutter/flutter/packages, so will need to be preserved 236 | # separately when moving to a shared file. 237 | - no_runtimeType_toString # use objectRuntimeType from package:foundation 238 | # - public_member_api_docs # see https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#documentation-dartdocs-javadocs-etc 239 | # Flutter has a specific use case for dependencies that are intentionally 240 | # not sorted, which doesn't apply to this repo. 241 | # - sort_pub_dependencies 242 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | BDA9DEF1F377B2F59E37C3C8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F038C2E9361B5384BA717598 /* Pods_Runner.framework */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 35 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 36 | 6DF9A02E3BC6BE5E9B07D0DB /* 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 = ""; }; 37 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 38 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 40 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 41 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 42 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 44 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 45 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 46 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47 | D645BD81BFF71AAD85C251F8 /* 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 = ""; }; 48 | F038C2E9361B5384BA717598 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | F816DD3D92F60DE35A850741 /* 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 = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | BDA9DEF1F377B2F59E37C3C8 /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 9740EEB11CF90186004384FC /* Flutter */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 68 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 70 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 71 | ); 72 | name = Flutter; 73 | sourceTree = ""; 74 | }; 75 | 97C146E51CF9000F007C117D = { 76 | isa = PBXGroup; 77 | children = ( 78 | 9740EEB11CF90186004384FC /* Flutter */, 79 | 97C146F01CF9000F007C117D /* Runner */, 80 | 97C146EF1CF9000F007C117D /* Products */, 81 | A0BC32BDDC1130CC32CD6973 /* Pods */, 82 | F812AE6EFBBBBC310A6FE8FC /* Frameworks */, 83 | ); 84 | sourceTree = ""; 85 | }; 86 | 97C146EF1CF9000F007C117D /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146EE1CF9000F007C117D /* Runner.app */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | 97C146F01CF9000F007C117D /* Runner */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 98 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 99 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 100 | 97C147021CF9000F007C117D /* Info.plist */, 101 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 102 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 103 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 104 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 105 | ); 106 | path = Runner; 107 | sourceTree = ""; 108 | }; 109 | A0BC32BDDC1130CC32CD6973 /* Pods */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | D645BD81BFF71AAD85C251F8 /* Pods-Runner.debug.xcconfig */, 113 | 6DF9A02E3BC6BE5E9B07D0DB /* Pods-Runner.release.xcconfig */, 114 | F816DD3D92F60DE35A850741 /* Pods-Runner.profile.xcconfig */, 115 | ); 116 | path = Pods; 117 | sourceTree = ""; 118 | }; 119 | F812AE6EFBBBBC310A6FE8FC /* Frameworks */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | F038C2E9361B5384BA717598 /* Pods_Runner.framework */, 123 | ); 124 | name = Frameworks; 125 | sourceTree = ""; 126 | }; 127 | /* End PBXGroup section */ 128 | 129 | /* Begin PBXNativeTarget section */ 130 | 97C146ED1CF9000F007C117D /* Runner */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 133 | buildPhases = ( 134 | 19604E92C53BCF1FCEF9860D /* [CP] Check Pods Manifest.lock */, 135 | 9740EEB61CF901F6004384FC /* Run Script */, 136 | 97C146EA1CF9000F007C117D /* Sources */, 137 | 97C146EB1CF9000F007C117D /* Frameworks */, 138 | 97C146EC1CF9000F007C117D /* Resources */, 139 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 140 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 141 | B3E1792B285554A740C074EA /* [CP] Embed Pods Frameworks */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = Runner; 148 | productName = Runner; 149 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | 97C146E61CF9000F007C117D /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | LastUpgradeCheck = 1510; 159 | ORGANIZATIONNAME = ""; 160 | TargetAttributes = { 161 | 97C146ED1CF9000F007C117D = { 162 | CreatedOnToolsVersion = 7.3.1; 163 | LastSwiftMigration = 1100; 164 | }; 165 | }; 166 | }; 167 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 168 | compatibilityVersion = "Xcode 9.3"; 169 | developmentRegion = en; 170 | hasScannedForEncodings = 0; 171 | knownRegions = ( 172 | en, 173 | Base, 174 | ); 175 | mainGroup = 97C146E51CF9000F007C117D; 176 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 177 | projectDirPath = ""; 178 | projectRoot = ""; 179 | targets = ( 180 | 97C146ED1CF9000F007C117D /* Runner */, 181 | ); 182 | }; 183 | /* End PBXProject section */ 184 | 185 | /* Begin PBXResourcesBuildPhase section */ 186 | 97C146EC1CF9000F007C117D /* Resources */ = { 187 | isa = PBXResourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 191 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 192 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 193 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | /* End PBXResourcesBuildPhase section */ 198 | 199 | /* Begin PBXShellScriptBuildPhase section */ 200 | 19604E92C53BCF1FCEF9860D /* [CP] Check Pods Manifest.lock */ = { 201 | isa = PBXShellScriptBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | ); 205 | inputFileListPaths = ( 206 | ); 207 | inputPaths = ( 208 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 209 | "${PODS_ROOT}/Manifest.lock", 210 | ); 211 | name = "[CP] Check Pods Manifest.lock"; 212 | outputFileListPaths = ( 213 | ); 214 | outputPaths = ( 215 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 216 | ); 217 | runOnlyForDeploymentPostprocessing = 0; 218 | shellPath = /bin/sh; 219 | 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"; 220 | showEnvVarsInLog = 0; 221 | }; 222 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 223 | isa = PBXShellScriptBuildPhase; 224 | alwaysOutOfDate = 1; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | ); 228 | inputPaths = ( 229 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 230 | ); 231 | name = "Thin Binary"; 232 | outputPaths = ( 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | shellPath = /bin/sh; 236 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 237 | }; 238 | 9740EEB61CF901F6004384FC /* Run Script */ = { 239 | isa = PBXShellScriptBuildPhase; 240 | alwaysOutOfDate = 1; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | ); 244 | inputPaths = ( 245 | ); 246 | name = "Run Script"; 247 | outputPaths = ( 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 252 | }; 253 | B3E1792B285554A740C074EA /* [CP] Embed Pods Frameworks */ = { 254 | isa = PBXShellScriptBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputFileListPaths = ( 259 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 260 | ); 261 | name = "[CP] Embed Pods Frameworks"; 262 | outputFileListPaths = ( 263 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | shellPath = /bin/sh; 267 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 268 | showEnvVarsInLog = 0; 269 | }; 270 | /* End PBXShellScriptBuildPhase section */ 271 | 272 | /* Begin PBXSourcesBuildPhase section */ 273 | 97C146EA1CF9000F007C117D /* Sources */ = { 274 | isa = PBXSourcesBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 278 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | /* End PBXSourcesBuildPhase section */ 283 | 284 | /* Begin PBXVariantGroup section */ 285 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 286 | isa = PBXVariantGroup; 287 | children = ( 288 | 97C146FB1CF9000F007C117D /* Base */, 289 | ); 290 | name = Main.storyboard; 291 | sourceTree = ""; 292 | }; 293 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 294 | isa = PBXVariantGroup; 295 | children = ( 296 | 97C147001CF9000F007C117D /* Base */, 297 | ); 298 | name = LaunchScreen.storyboard; 299 | sourceTree = ""; 300 | }; 301 | /* End PBXVariantGroup section */ 302 | 303 | /* Begin XCBuildConfiguration section */ 304 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ALWAYS_SEARCH_USER_PATHS = NO; 308 | CLANG_ANALYZER_NONNULL = YES; 309 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 310 | CLANG_CXX_LIBRARY = "libc++"; 311 | CLANG_ENABLE_MODULES = YES; 312 | CLANG_ENABLE_OBJC_ARC = YES; 313 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 314 | CLANG_WARN_BOOL_CONVERSION = YES; 315 | CLANG_WARN_COMMA = YES; 316 | CLANG_WARN_CONSTANT_CONVERSION = YES; 317 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 319 | CLANG_WARN_EMPTY_BODY = YES; 320 | CLANG_WARN_ENUM_CONVERSION = YES; 321 | CLANG_WARN_INFINITE_RECURSION = YES; 322 | CLANG_WARN_INT_CONVERSION = YES; 323 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 325 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 326 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 327 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 328 | CLANG_WARN_STRICT_PROTOTYPES = YES; 329 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 330 | CLANG_WARN_UNREACHABLE_CODE = YES; 331 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 332 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 333 | COPY_PHASE_STRIP = NO; 334 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 335 | ENABLE_NS_ASSERTIONS = NO; 336 | ENABLE_STRICT_OBJC_MSGSEND = YES; 337 | GCC_C_LANGUAGE_STANDARD = gnu99; 338 | GCC_NO_COMMON_BLOCKS = YES; 339 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 340 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 341 | GCC_WARN_UNDECLARED_SELECTOR = YES; 342 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 343 | GCC_WARN_UNUSED_FUNCTION = YES; 344 | GCC_WARN_UNUSED_VARIABLE = YES; 345 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 346 | MTL_ENABLE_DEBUG_INFO = NO; 347 | SDKROOT = iphoneos; 348 | SUPPORTED_PLATFORMS = iphoneos; 349 | TARGETED_DEVICE_FAMILY = "1,2"; 350 | VALIDATE_PRODUCT = YES; 351 | }; 352 | name = Profile; 353 | }; 354 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 355 | isa = XCBuildConfiguration; 356 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 357 | buildSettings = { 358 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 359 | CLANG_ENABLE_MODULES = YES; 360 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 361 | DEVELOPMENT_TEAM = FN2LK8W6BR; 362 | ENABLE_BITCODE = NO; 363 | INFOPLIST_FILE = Runner/Info.plist; 364 | LD_RUNPATH_SEARCH_PATHS = ( 365 | "$(inherited)", 366 | "@executable_path/Frameworks", 367 | ); 368 | PRODUCT_BUNDLE_IDENTIFIER = com.example.localePlusExample; 369 | PRODUCT_NAME = "$(TARGET_NAME)"; 370 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 371 | SWIFT_VERSION = 5.0; 372 | VERSIONING_SYSTEM = "apple-generic"; 373 | }; 374 | name = Profile; 375 | }; 376 | 97C147031CF9000F007C117D /* Debug */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ALWAYS_SEARCH_USER_PATHS = NO; 380 | CLANG_ANALYZER_NONNULL = YES; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_MODULES = YES; 384 | CLANG_ENABLE_OBJC_ARC = YES; 385 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 386 | CLANG_WARN_BOOL_CONVERSION = YES; 387 | CLANG_WARN_COMMA = YES; 388 | CLANG_WARN_CONSTANT_CONVERSION = YES; 389 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_EMPTY_BODY = YES; 392 | CLANG_WARN_ENUM_CONVERSION = YES; 393 | CLANG_WARN_INFINITE_RECURSION = YES; 394 | CLANG_WARN_INT_CONVERSION = YES; 395 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 396 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 397 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 399 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 400 | CLANG_WARN_STRICT_PROTOTYPES = YES; 401 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 402 | CLANG_WARN_UNREACHABLE_CODE = YES; 403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 404 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 405 | COPY_PHASE_STRIP = NO; 406 | DEBUG_INFORMATION_FORMAT = dwarf; 407 | ENABLE_STRICT_OBJC_MSGSEND = YES; 408 | ENABLE_TESTABILITY = YES; 409 | GCC_C_LANGUAGE_STANDARD = gnu99; 410 | GCC_DYNAMIC_NO_PIC = NO; 411 | GCC_NO_COMMON_BLOCKS = YES; 412 | GCC_OPTIMIZATION_LEVEL = 0; 413 | GCC_PREPROCESSOR_DEFINITIONS = ( 414 | "DEBUG=1", 415 | "$(inherited)", 416 | ); 417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 419 | GCC_WARN_UNDECLARED_SELECTOR = YES; 420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 421 | GCC_WARN_UNUSED_FUNCTION = YES; 422 | GCC_WARN_UNUSED_VARIABLE = YES; 423 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 424 | MTL_ENABLE_DEBUG_INFO = YES; 425 | ONLY_ACTIVE_ARCH = YES; 426 | SDKROOT = iphoneos; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | }; 429 | name = Debug; 430 | }; 431 | 97C147041CF9000F007C117D /* Release */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ALWAYS_SEARCH_USER_PATHS = NO; 435 | CLANG_ANALYZER_NONNULL = YES; 436 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 437 | CLANG_CXX_LIBRARY = "libc++"; 438 | CLANG_ENABLE_MODULES = YES; 439 | CLANG_ENABLE_OBJC_ARC = YES; 440 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 441 | CLANG_WARN_BOOL_CONVERSION = YES; 442 | CLANG_WARN_COMMA = YES; 443 | CLANG_WARN_CONSTANT_CONVERSION = YES; 444 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 445 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INFINITE_RECURSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 451 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 452 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 453 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 454 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 455 | CLANG_WARN_STRICT_PROTOTYPES = YES; 456 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 457 | CLANG_WARN_UNREACHABLE_CODE = YES; 458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 460 | COPY_PHASE_STRIP = NO; 461 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 462 | ENABLE_NS_ASSERTIONS = NO; 463 | ENABLE_STRICT_OBJC_MSGSEND = YES; 464 | GCC_C_LANGUAGE_STANDARD = gnu99; 465 | GCC_NO_COMMON_BLOCKS = YES; 466 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 467 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 468 | GCC_WARN_UNDECLARED_SELECTOR = YES; 469 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 470 | GCC_WARN_UNUSED_FUNCTION = YES; 471 | GCC_WARN_UNUSED_VARIABLE = YES; 472 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 473 | MTL_ENABLE_DEBUG_INFO = NO; 474 | SDKROOT = iphoneos; 475 | SUPPORTED_PLATFORMS = iphoneos; 476 | SWIFT_COMPILATION_MODE = wholemodule; 477 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 478 | TARGETED_DEVICE_FAMILY = "1,2"; 479 | VALIDATE_PRODUCT = YES; 480 | }; 481 | name = Release; 482 | }; 483 | 97C147061CF9000F007C117D /* Debug */ = { 484 | isa = XCBuildConfiguration; 485 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 486 | buildSettings = { 487 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 488 | CLANG_ENABLE_MODULES = YES; 489 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 490 | DEVELOPMENT_TEAM = FN2LK8W6BR; 491 | ENABLE_BITCODE = NO; 492 | INFOPLIST_FILE = Runner/Info.plist; 493 | LD_RUNPATH_SEARCH_PATHS = ( 494 | "$(inherited)", 495 | "@executable_path/Frameworks", 496 | ); 497 | PRODUCT_BUNDLE_IDENTIFIER = com.example.localePlusExample; 498 | PRODUCT_NAME = "$(TARGET_NAME)"; 499 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 500 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 501 | SWIFT_VERSION = 5.0; 502 | VERSIONING_SYSTEM = "apple-generic"; 503 | }; 504 | name = Debug; 505 | }; 506 | 97C147071CF9000F007C117D /* Release */ = { 507 | isa = XCBuildConfiguration; 508 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 509 | buildSettings = { 510 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 511 | CLANG_ENABLE_MODULES = YES; 512 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 513 | DEVELOPMENT_TEAM = YQQ79ZQVRE; 514 | ENABLE_BITCODE = NO; 515 | INFOPLIST_FILE = Runner/Info.plist; 516 | LD_RUNPATH_SEARCH_PATHS = ( 517 | "$(inherited)", 518 | "@executable_path/Frameworks", 519 | ); 520 | PRODUCT_BUNDLE_IDENTIFIER = com.example.localePlusExample; 521 | PRODUCT_NAME = "$(TARGET_NAME)"; 522 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 523 | SWIFT_VERSION = 5.0; 524 | VERSIONING_SYSTEM = "apple-generic"; 525 | }; 526 | name = Release; 527 | }; 528 | /* End XCBuildConfiguration section */ 529 | 530 | /* Begin XCConfigurationList section */ 531 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 532 | isa = XCConfigurationList; 533 | buildConfigurations = ( 534 | 97C147031CF9000F007C117D /* Debug */, 535 | 97C147041CF9000F007C117D /* Release */, 536 | 249021D3217E4FDB00AE95B9 /* Profile */, 537 | ); 538 | defaultConfigurationIsVisible = 0; 539 | defaultConfigurationName = Release; 540 | }; 541 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 542 | isa = XCConfigurationList; 543 | buildConfigurations = ( 544 | 97C147061CF9000F007C117D /* Debug */, 545 | 97C147071CF9000F007C117D /* Release */, 546 | 249021D4217E4FDB00AE95B9 /* Profile */, 547 | ); 548 | defaultConfigurationIsVisible = 0; 549 | defaultConfigurationName = Release; 550 | }; 551 | /* End XCConfigurationList section */ 552 | }; 553 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 554 | } 555 | --------------------------------------------------------------------------------