From b6997b4e1db65f753f88d77b0f8c83b164c65c9a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 8 Mar 2026 10:15:47 -0600 Subject: [PATCH 1/7] app: Add CocoaPods configuration for iOS and macOS builds Co-Authored-By: Claude Opus 4.6 --- app/ios/Flutter/Debug.xcconfig | 1 + app/ios/Flutter/Release.xcconfig | 1 + app/ios/Podfile | 43 ++++++ app/ios/Podfile.lock | 55 ++++++++ app/ios/Runner.xcodeproj/project.pbxproj | 123 ++++++++++++++++++ .../contents.xcworkspacedata | 3 + app/macos/Flutter/Flutter-Debug.xcconfig | 1 + app/macos/Flutter/Flutter-Release.xcconfig | 1 + app/macos/Podfile | 42 ++++++ app/macos/Podfile.lock | 55 ++++++++ app/macos/Runner.xcodeproj/project.pbxproj | 98 +++++++++++++- .../contents.xcworkspacedata | 3 + 12 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 app/ios/Podfile create mode 100644 app/ios/Podfile.lock create mode 100644 app/macos/Podfile create mode 100644 app/macos/Podfile.lock diff --git a/app/ios/Flutter/Debug.xcconfig b/app/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/app/ios/Flutter/Debug.xcconfig +++ b/app/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/app/ios/Flutter/Release.xcconfig b/app/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/app/ios/Flutter/Release.xcconfig +++ b/app/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/app/ios/Podfile b/app/ios/Podfile new file mode 100644 index 0000000..620e46e --- /dev/null +++ b/app/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '13.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/app/ios/Podfile.lock b/app/ios/Podfile.lock new file mode 100644 index 0000000..b29c503 --- /dev/null +++ b/app/ios/Podfile.lock @@ -0,0 +1,55 @@ +PODS: + - Flutter (1.0.0) + - package_info_plus (0.4.5): + - Flutter + - pdfrx (0.0.6): + - Flutter + - FlutterMacOS + - printing (1.0.0): + - Flutter + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite_darwin (0.0.4): + - Flutter + - FlutterMacOS + - url_launcher_ios (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - pdfrx (from `.symlinks/plugins/pdfrx/darwin`) + - printing (from `.symlinks/plugins/printing/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + pdfrx: + :path: ".symlinks/plugins/pdfrx/darwin" + printing: + :path: ".symlinks/plugins/printing/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sqflite_darwin: + :path: ".symlinks/plugins/sqflite_darwin/darwin" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + +SPEC CHECKSUMS: + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + pdfrx: 310e84d01e06fd2af26e16507a0e48c27e99195c + printing: 54ff03f28fe9ba3aa93358afb80a8595a071dd07 + shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 + url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b + +PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e + +COCOAPODS: 1.16.2 diff --git a/app/ios/Runner.xcodeproj/project.pbxproj b/app/ios/Runner.xcodeproj/project.pbxproj index 86da486..0285236 100644 --- a/app/ios/Runner.xcodeproj/project.pbxproj +++ b/app/ios/Runner.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + E4C6D7EE65800263D4DF3814 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E723ADC188EE985D34F6E70 /* Pods_Runner.framework */; }; + F2265329264FCEDAAE01FC70 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2363D5065B231C6D039D8D4A /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -43,6 +45,9 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 1ECB22CAC41650FE8E39BD06 /* 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 = ""; }; + 2363D5065B231C6D039D8D4A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2E723ADC188EE985D34F6E70 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; @@ -50,6 +55,10 @@ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 885CF4148C12FFA6753E0E24 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 88C9DDFECDFFC57CD8036601 /* 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 = ""; }; + 8A816B95B285B226DCB68D64 /* 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 = ""; }; + 908778FA374EC97D926528D8 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -57,6 +66,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9A752E34EA36FC294C049282 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -64,12 +74,30 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E4C6D7EE65800263D4DF3814 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE34F64C577E0980106D8D00 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F2265329264FCEDAAE01FC70 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 013B4BEA21BB5A72221B2928 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2E723ADC188EE985D34F6E70 /* Pods_Runner.framework */, + 2363D5065B231C6D039D8D4A /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 331C8082294A63A400263BE5 /* RunnerTests */ = { isa = PBXGroup; children = ( @@ -96,6 +124,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + ABE0B4894FCDC13CCFF7E39D /* Pods */, + 013B4BEA21BB5A72221B2928 /* Frameworks */, ); sourceTree = ""; }; @@ -124,6 +154,19 @@ path = Runner; sourceTree = ""; }; + ABE0B4894FCDC13CCFF7E39D /* Pods */ = { + isa = PBXGroup; + children = ( + 88C9DDFECDFFC57CD8036601 /* Pods-Runner.debug.xcconfig */, + 8A816B95B285B226DCB68D64 /* Pods-Runner.release.xcconfig */, + 1ECB22CAC41650FE8E39BD06 /* Pods-Runner.profile.xcconfig */, + 908778FA374EC97D926528D8 /* Pods-RunnerTests.debug.xcconfig */, + 885CF4148C12FFA6753E0E24 /* Pods-RunnerTests.release.xcconfig */, + 9A752E34EA36FC294C049282 /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -131,8 +174,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + D1813CA71963656B7741EE9F /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + EE34F64C577E0980106D8D00 /* Frameworks */, ); buildRules = ( ); @@ -148,12 +193,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 856D820975942F711B85AF63 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 5C9ACC93FCE43D9895667CDC /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -241,6 +288,45 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 5C9ACC93FCE43D9895667CDC /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 856D820975942F711B85AF63 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -256,6 +342,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + D1813CA71963656B7741EE9F /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -365,7 +473,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 478BD42F7R; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -374,6 +485,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.paperman.paperman; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -382,6 +494,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 908778FA374EC97D926528D8 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -399,6 +512,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 885CF4148C12FFA6753E0E24 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -414,6 +528,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9A752E34EA36FC294C049282 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -544,7 +659,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 478BD42F7R; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -553,6 +671,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.paperman.paperman; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -566,7 +685,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 478BD42F7R; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -575,6 +697,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.paperman.paperman; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/app/ios/Runner.xcworkspace/contents.xcworkspacedata b/app/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/app/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/app/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/app/macos/Flutter/Flutter-Debug.xcconfig b/app/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b..4b81f9b 100644 --- a/app/macos/Flutter/Flutter-Debug.xcconfig +++ b/app/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/app/macos/Flutter/Flutter-Release.xcconfig b/app/macos/Flutter/Flutter-Release.xcconfig index c2efd0b..5caa9d1 100644 --- a/app/macos/Flutter/Flutter-Release.xcconfig +++ b/app/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/app/macos/Podfile b/app/macos/Podfile new file mode 100644 index 0000000..ff5ddb3 --- /dev/null +++ b/app/macos/Podfile @@ -0,0 +1,42 @@ +platform :osx, '10.15' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/app/macos/Podfile.lock b/app/macos/Podfile.lock new file mode 100644 index 0000000..2560cb2 --- /dev/null +++ b/app/macos/Podfile.lock @@ -0,0 +1,55 @@ +PODS: + - FlutterMacOS (1.0.0) + - package_info_plus (0.0.1): + - FlutterMacOS + - pdfrx (0.0.6): + - Flutter + - FlutterMacOS + - printing (1.0.0): + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite_darwin (0.0.4): + - Flutter + - FlutterMacOS + - url_launcher_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) + - pdfrx (from `Flutter/ephemeral/.symlinks/plugins/pdfrx/darwin`) + - printing (from `Flutter/ephemeral/.symlinks/plugins/printing/macos`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + package_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos + pdfrx: + :path: Flutter/ephemeral/.symlinks/plugins/pdfrx/darwin + printing: + :path: Flutter/ephemeral/.symlinks/plugins/printing/macos + shared_preferences_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + sqflite_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + +SPEC CHECKSUMS: + FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 + package_info_plus: f0052d280d17aa382b932f399edf32507174e870 + pdfrx: 310e84d01e06fd2af26e16507a0e48c27e99195c + printing: c4cf83c78fd684f9bc318e6aadc18972aa48f617 + shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 + url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd + +PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009 + +COCOAPODS: 1.16.2 diff --git a/app/macos/Runner.xcodeproj/project.pbxproj b/app/macos/Runner.xcodeproj/project.pbxproj index 78a61b9..2fd5831 100644 --- a/app/macos/Runner.xcodeproj/project.pbxproj +++ b/app/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + B6C776CD8472A5D7B823749E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C899683BFD99A1E47AC3C8E /* Pods_Runner.framework */; }; + C8F71FD30B762137DBCFCDAD /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DF9BC870F049C44C0065AA6 /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,11 +62,13 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 1A765DFE23283DC61356E0A7 /* 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 = ""; }; + 2DF9BC870F049C44C0065AA6 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* paperman.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "paperman.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* paperman.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = paperman.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -76,8 +80,14 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 6C899683BFD99A1E47AC3C8E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + 9BD4DEE250451E70E3E24EBD /* 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 = ""; }; + B1F647CB4697F0C91A48D3CE /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + BF5487D36B9648BCA279F85D /* 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 = ""; }; + C2A6271AD11D4D034BEEF140 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + C898A64419906FA809DA3466 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +95,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C8F71FD30B762137DBCFCDAD /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,6 +103,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B6C776CD8472A5D7B823749E /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -125,6 +137,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + D4FD66792EF69D8274E8AA95 /* Pods */, ); sourceTree = ""; }; @@ -172,9 +185,25 @@ path = Runner; sourceTree = ""; }; + D4FD66792EF69D8274E8AA95 /* Pods */ = { + isa = PBXGroup; + children = ( + 1A765DFE23283DC61356E0A7 /* Pods-Runner.debug.xcconfig */, + BF5487D36B9648BCA279F85D /* Pods-Runner.release.xcconfig */, + 9BD4DEE250451E70E3E24EBD /* Pods-Runner.profile.xcconfig */, + C2A6271AD11D4D034BEEF140 /* Pods-RunnerTests.debug.xcconfig */, + C898A64419906FA809DA3466 /* Pods-RunnerTests.release.xcconfig */, + B1F647CB4697F0C91A48D3CE /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + 6C899683BFD99A1E47AC3C8E /* Pods_Runner.framework */, + 2DF9BC870F049C44C0065AA6 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -186,6 +215,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 578B95DD1E5B57CACE86D7E8 /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -204,11 +234,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 17ED4188CC2D145F37861D15 /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + 7A777ED0BA23A6B974D88219 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -291,6 +323,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 17ED4188CC2D145F37861D15 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -329,6 +383,45 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + 578B95DD1E5B57CACE86D7E8 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 7A777ED0BA23A6B974D88219 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -380,6 +473,7 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C2A6271AD11D4D034BEEF140 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -394,6 +488,7 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C898A64419906FA809DA3466 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -408,6 +503,7 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = B1F647CB4697F0C91A48D3CE /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; diff --git a/app/macos/Runner.xcworkspace/contents.xcworkspacedata b/app/macos/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/app/macos/Runner.xcworkspace/contents.xcworkspacedata +++ b/app/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + From d5d642b91aa21074fc6708d3e5bd1fad3bd2edfe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 8 Mar 2026 10:15:58 -0600 Subject: [PATCH 2/7] app: Allow connecting with only a local URL Support specifying just the local URL without a server URL. The local URL is used as both the base and local URL so that the certificate- trusting client handles self-signed certificates correctly. Co-Authored-By: Claude Opus 4.6 --- app/lib/screens/connection_screen.dart | 34 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/app/lib/screens/connection_screen.dart b/app/lib/screens/connection_screen.dart index ef7a213..a49010e 100644 --- a/app/lib/screens/connection_screen.dart +++ b/app/lib/screens/connection_screen.dart @@ -49,7 +49,9 @@ class _ConnectionScreenState extends State { _userController.text = prefs.getString('username') ?? ''; _passController.text = prefs.getString('password') ?? ''; // Auto-connect if we have a saved URL (unless returning from disconnect) - if (widget.autoConnect && _urlController.text.isNotEmpty) { + if (widget.autoConnect && + (_urlController.text.isNotEmpty || + _localUrlController.text.isNotEmpty)) { _connect(); } } @@ -64,14 +66,29 @@ class _ConnectionScreenState extends State { Future _connect() async { var url = _urlController.text.trim(); - if (url.isEmpty) { - setState(() => _error = 'Please enter a server URL'); + var localUrl = _localUrlController.text.trim(); + if (url.isEmpty && localUrl.isEmpty) { + setState(() => _error = 'Please enter a server URL or local URL'); return; } - if (!url.startsWith('http://') && !url.startsWith('https://')) { + if (url.isNotEmpty && + !url.startsWith('http://') && + !url.startsWith('https://')) { url = 'https://$url'; _urlController.text = url; } + if (localUrl.isNotEmpty && + !localUrl.startsWith('http://') && + !localUrl.startsWith('https://')) { + final scheme = url.isNotEmpty ? Uri.parse(url).scheme : 'http'; + localUrl = '$scheme://$localUrl'; + _localUrlController.text = localUrl; + } + // If no server URL, use the local URL as both so that + // tryLocalUrl() creates a certificate-trusting client. + if (url.isEmpty) { + url = localUrl; + } setState(() { _connecting = true; @@ -81,15 +98,6 @@ class _ConnectionScreenState extends State { final api = context.read(); final user = _userController.text.trim(); final pass = _passController.text; - var localUrl = _localUrlController.text.trim(); - if (localUrl.isNotEmpty && - !localUrl.startsWith('http://') && - !localUrl.startsWith('https://')) { - // Use the same scheme as the main URL (e.g. https) - final scheme = Uri.parse(url).scheme; - localUrl = '$scheme://$localUrl'; - _localUrlController.text = localUrl; - } api.updateConfig( baseUrl: url, localBaseUrl: localUrl.isEmpty ? null : localUrl, From fbe1f5cef0e36f3f528ca0c2a2a5434a933edd4d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 8 Mar 2026 13:23:15 -0600 Subject: [PATCH 3/7] app: Pass PDF page dimensions to print system for correct scaling On iOS the printing plugin renders PDF pages at their native point size without scaling to fit the paper. Read the first page dimensions and pass them as the format so iOS picks matching paper and the rendering fills the page correctly. Co-Authored-By: Claude Opus 4.6 --- app/lib/screens/viewer_screen.dart | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/app/lib/screens/viewer_screen.dart b/app/lib/screens/viewer_screen.dart index 4a58b69..4ce23ba 100644 --- a/app/lib/screens/viewer_screen.dart +++ b/app/lib/screens/viewer_screen.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:pdf/pdf.dart' show PdfPageFormat; import 'package:pdfrx/pdfrx.dart'; import 'package:path_provider/path_provider.dart'; import 'package:printing/printing.dart'; @@ -496,7 +497,25 @@ class _ViewerScreenState extends State { if (!mounted || cancelled) return; Navigator.of(context).pop(); - await Printing.layoutPdf(onLayout: (_) => bytes); + + // Read the first page's dimensions so iOS prints at the correct + // scale instead of using a default paper size. + var format = PdfPageFormat.standard; + final pdfDoc = await PdfDocument.openData(bytes); + try { + if (pdfDoc.pages.isNotEmpty) { + final page = pdfDoc.pages[0]; + format = PdfPageFormat(page.width, page.height); + } + } finally { + pdfDoc.dispose(); + } + + await Printing.layoutPdf( + onLayout: (_) => bytes, + format: format, + dynamicLayout: false, + ); } catch (e) { if (!mounted || cancelled) return; Navigator.of(context).pop(); From 9e525fb383c3cfd8873dde1fef99f844cb5d76e4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 8 Mar 2026 13:23:34 -0600 Subject: [PATCH 4/7] Add app-ios and app-ios-install Makefile targets Add targets for building the iOS app with dart defines (build date) and installing via devicectl which preserves app settings, unlike flutter install which uninstalls first. Co-Authored-By: Claude Opus 4.6 --- GNUmakefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 4f64885..00a2e45 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -100,7 +100,7 @@ setup: scripts/setup.sh .PHONY: app app-demo app-test dart-defines app-apk app-aab app-publish -.PHONY: app-upload app-scp app-scp-only app-scp-watch app-linux app-clean +.PHONY: app-upload app-scp app-scp-only app-scp-watch app-ios app-ios-install app-linux app-clean dart-defines: @echo '{"BUILD_DATE":"$(BUILD_DATE)"}' > $(DART_DEFINES) @@ -135,6 +135,15 @@ app-scp-watch: scp $(APP_APK) $(APP_SERVER); \ done +app-ios: dart-defines + cd app && flutter build ios $(FLUTTER_ARGS) + +app-ios-install: app-ios + xcrun devicectl device install app --device $(IOS_DEVICE) $(APP_IOS) + +IOS_DEVICE ?= 00008122-0001786226E8401C +APP_IOS = app/build/ios/iphoneos/Runner.app + app-linux: dart-defines # Clear CMake cache so find_library() re-discovers libpdfium.so from # the printing plugin's download rather than a stale bundle/lib/ path. From 23619c7154e1d205eee77a6378c47f8bff96d512 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 8 Mar 2026 13:41:52 -0600 Subject: [PATCH 5/7] Fix grep -P usage for macOS compatibility macOS BSD grep does not support -P (Perl regex). Replace with sed which works on both GNU and BSD systems. Co-Authored-By: Claude Opus 4.6 --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 00a2e45..22ab9f0 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -53,7 +53,7 @@ app: app-apk app-linux rm -f $(DART_DEFINES) GH_REMOTE ?= gh -DEB_VERSION := $(shell head -1 debian/changelog.in | grep -oP '\(\K[^)]+' | sed 's/VENDOR_VERSION//') +DEB_VERSION := $(shell head -1 debian/changelog.in | sed -n 's/.*(\([^)]*\)).*/\1/p' | sed 's/VENDOR_VERSION//') DEB_UPSTREAM := $(firstword $(subst -, ,$(DEB_VERSION))) RELEASE_TAG = v$(DEB_UPSTREAM) RELEASE_DEBS = $(wildcard ../release/all/paperman_$(DEB_VERSION)_*.deb) From e266aa7b06e8cbce5fb528d5c77f4cc6fb2f9e17 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 8 Mar 2026 15:10:11 -0600 Subject: [PATCH 6/7] app: Default local URL scheme to https When a local URL is entered without a scheme and no server URL is provided, default to https instead of http since local servers typically use self-signed TLS certificates. Co-Authored-By: Claude Opus 4.6 --- app/lib/screens/connection_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/screens/connection_screen.dart b/app/lib/screens/connection_screen.dart index a49010e..0b1d6db 100644 --- a/app/lib/screens/connection_screen.dart +++ b/app/lib/screens/connection_screen.dart @@ -80,7 +80,7 @@ class _ConnectionScreenState extends State { if (localUrl.isNotEmpty && !localUrl.startsWith('http://') && !localUrl.startsWith('https://')) { - final scheme = url.isNotEmpty ? Uri.parse(url).scheme : 'http'; + final scheme = url.isNotEmpty ? Uri.parse(url).scheme : 'https'; localUrl = '$scheme://$localUrl'; _localUrlController.text = localUrl; } From c1c31bb15da480ebbe15382fad0f606e8e661d1c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 8 Mar 2026 15:54:48 -0600 Subject: [PATCH 7/7] app: Add pdf as direct dependency and document IOS_DEVICE The pdf package is imported directly in viewer_screen.dart for PdfPageFormat, so it must be listed as a direct dependency to satisfy the depend_on_referenced_packages lint. Also add a comment explaining how to set IOS_DEVICE in the Makefile. Co-Authored-By: Claude Opus 4.6 --- GNUmakefile | 2 ++ app/pubspec.lock | 2 +- app/pubspec.yaml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 22ab9f0..d217de8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -141,6 +141,8 @@ app-ios: dart-defines app-ios-install: app-ios xcrun devicectl device install app --device $(IOS_DEVICE) $(APP_IOS) +# Set IOS_DEVICE to your iPad/iPhone device ID (from Xcode or +# `xcrun devicectl list devices`). IOS_DEVICE ?= 00008122-0001786226E8401C APP_IOS = app/build/ios/iphoneos/Runner.app diff --git a/app/pubspec.lock b/app/pubspec.lock index 61b1881..86b3313 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -561,7 +561,7 @@ packages: source: hosted version: "2.3.0" pdf: - dependency: transitive + dependency: "direct main" description: name: pdf sha256: "28eacad99bffcce2e05bba24e50153890ad0255294f4dd78a17075a2ba5c8416" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 7154da6..ba7f550 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: path_provider: ^2.1.0 package_info_plus: ^8.0.0 url_launcher: ^6.2.0 + pdf: ^3.0.0 printing: ^5.13.0 dev_dependencies: