diff --git a/ios/PushDeer-iOS/.gitignore b/ios/PushDeer-iOS/.gitignore new file mode 100644 index 0000000..2c6e72c --- /dev/null +++ b/ios/PushDeer-iOS/.gitignore @@ -0,0 +1,114 @@ +# General +.DS_Store +.AppleDouble +.LSOverride + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ diff --git a/ios/PushDeer-iOS/LICENSE b/ios/PushDeer-iOS/LICENSE new file mode 100644 index 0000000..1dbac0f --- /dev/null +++ b/ios/PushDeer-iOS/LICENSE @@ -0,0 +1 @@ +本项目禁止商用(包括但不限于搭建后挂广告或售卖会员、打包后上架商店销售等),对非商业用途采用 GPLV2 授权 diff --git a/ios/PushDeer-iOS/PushDeer.xcodeproj/project.pbxproj b/ios/PushDeer-iOS/PushDeer.xcodeproj/project.pbxproj new file mode 100644 index 0000000..54ffd5c --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer.xcodeproj/project.pbxproj @@ -0,0 +1,421 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 52163EB327773F8400594190 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB227773F8400594190 /* MainView.swift */; }; + 52163EB52777413B00594190 /* MessageListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB42777413B00594190 /* MessageListView.swift */; }; + 52163EB72777415F00594190 /* DeviceListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB62777415F00594190 /* DeviceListView.swift */; }; + 52163EB92777417900594190 /* KeyListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EB82777417900594190 /* KeyListView.swift */; }; + 52163EBB277741AC00594190 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52163EBA277741AC00594190 /* SettingsView.swift */; }; + 523150D9277875FB00941EDC /* DeletableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523150D8277875FB00941EDC /* DeletableView.swift */; }; + 523150DC2778762B00941EDC /* DeviceItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523150DB2778762B00941EDC /* DeviceItemView.swift */; }; + 5292F4F92776BC7900B9A7BB /* PushDeerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5292F4F82776BC7900B9A7BB /* PushDeerApp.swift */; }; + 5292F4FB2776BC7900B9A7BB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5292F4FA2776BC7900B9A7BB /* ContentView.swift */; }; + 5292F4FD2776BC7A00B9A7BB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5292F4FC2776BC7A00B9A7BB /* Assets.xcassets */; }; + 5292F5002776BC7A00B9A7BB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5292F4FF2776BC7A00B9A7BB /* Preview Assets.xcassets */; }; + 52EB90AC2778ADF80048E0ED /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AB2778ADF80048E0ED /* CardView.swift */; }; + 52EB90AE2778AFD60048E0ED /* BaseNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AD2778AFD60048E0ED /* BaseNavigationView.swift */; }; + 52EB90B02778D67F0048E0ED /* KeyItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90AF2778D67F0048E0ED /* KeyItemView.swift */; }; + 52EB90B32778DA4E0048E0ED /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90B22778DA4E0048E0ED /* Line.swift */; }; + 52F0243F277737470071D861 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F0243E277737470071D861 /* LoginView.swift */; }; + 52F2C223277961D7006F08DC /* SettingsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F2C222277961D7006F08DC /* SettingsItemView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 52163EB227773F8400594190 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; + 52163EB42777413B00594190 /* MessageListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListView.swift; sourceTree = ""; }; + 52163EB62777415F00594190 /* DeviceListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceListView.swift; sourceTree = ""; }; + 52163EB82777417900594190 /* KeyListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyListView.swift; sourceTree = ""; }; + 52163EBA277741AC00594190 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; + 523150D8277875FB00941EDC /* DeletableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletableView.swift; sourceTree = ""; }; + 523150DB2778762B00941EDC /* DeviceItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceItemView.swift; sourceTree = ""; }; + 5292F4F52776BC7900B9A7BB /* PushDeer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PushDeer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5292F4F82776BC7900B9A7BB /* PushDeerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushDeerApp.swift; sourceTree = ""; }; + 5292F4FA2776BC7900B9A7BB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 5292F4FC2776BC7A00B9A7BB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5292F4FF2776BC7A00B9A7BB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 52EB90AB2778ADF80048E0ED /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = ""; }; + 52EB90AD2778AFD60048E0ED /* BaseNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNavigationView.swift; sourceTree = ""; }; + 52EB90AF2778D67F0048E0ED /* KeyItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyItemView.swift; sourceTree = ""; }; + 52EB90B22778DA4E0048E0ED /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; + 52F0243C277733CE0071D861 /* PushDeer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushDeer.entitlements; sourceTree = ""; }; + 52F0243E277737470071D861 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = ""; }; + 52F2C222277961D7006F08DC /* SettingsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsItemView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5292F4F22776BC7900B9A7BB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5292F4EC2776BC7900B9A7BB = { + isa = PBXGroup; + children = ( + 5292F4F72776BC7900B9A7BB /* PushDeer */, + 5292F4F62776BC7900B9A7BB /* Products */, + ); + indentWidth = 2; + sourceTree = ""; + }; + 5292F4F62776BC7900B9A7BB /* Products */ = { + isa = PBXGroup; + children = ( + 5292F4F52776BC7900B9A7BB /* PushDeer.app */, + ); + name = Products; + sourceTree = ""; + }; + 5292F4F72776BC7900B9A7BB /* PushDeer */ = { + isa = PBXGroup; + children = ( + 52F0243D2777370F0071D861 /* View */, + 52F0243C277733CE0071D861 /* PushDeer.entitlements */, + 5292F4F82776BC7900B9A7BB /* PushDeerApp.swift */, + 5292F4FA2776BC7900B9A7BB /* ContentView.swift */, + 5292F4FC2776BC7A00B9A7BB /* Assets.xcassets */, + 5292F4FE2776BC7A00B9A7BB /* Preview Content */, + ); + path = PushDeer; + sourceTree = ""; + }; + 5292F4FE2776BC7A00B9A7BB /* Preview Content */ = { + isa = PBXGroup; + children = ( + 5292F4FF2776BC7A00B9A7BB /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 52EB90B12778D9F90048E0ED /* Common */ = { + isa = PBXGroup; + children = ( + 52EB90AD2778AFD60048E0ED /* BaseNavigationView.swift */, + 523150D8277875FB00941EDC /* DeletableView.swift */, + 52EB90AB2778ADF80048E0ED /* CardView.swift */, + 52EB90B22778DA4E0048E0ED /* Line.swift */, + ); + path = Common; + sourceTree = ""; + }; + 52F0243D2777370F0071D861 /* View */ = { + isa = PBXGroup; + children = ( + 52EB90B12778D9F90048E0ED /* Common */, + 52F0243E277737470071D861 /* LoginView.swift */, + 52163EB227773F8400594190 /* MainView.swift */, + 52163EB62777415F00594190 /* DeviceListView.swift */, + 52163EB82777417900594190 /* KeyListView.swift */, + 52163EB42777413B00594190 /* MessageListView.swift */, + 52163EBA277741AC00594190 /* SettingsView.swift */, + 523150DB2778762B00941EDC /* DeviceItemView.swift */, + 52EB90AF2778D67F0048E0ED /* KeyItemView.swift */, + 52F2C222277961D7006F08DC /* SettingsItemView.swift */, + ); + path = View; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5292F4F42776BC7900B9A7BB /* PushDeer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5292F5032776BC7A00B9A7BB /* Build configuration list for PBXNativeTarget "PushDeer" */; + buildPhases = ( + 5292F4F12776BC7900B9A7BB /* Sources */, + 5292F4F22776BC7900B9A7BB /* Frameworks */, + 5292F4F32776BC7900B9A7BB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PushDeer; + productName = PushDeer; + productReference = 5292F4F52776BC7900B9A7BB /* PushDeer.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5292F4ED2776BC7900B9A7BB /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1320; + LastUpgradeCheck = 1320; + TargetAttributes = { + 5292F4F42776BC7900B9A7BB = { + CreatedOnToolsVersion = 13.2.1; + }; + }; + }; + buildConfigurationList = 5292F4F02776BC7900B9A7BB /* Build configuration list for PBXProject "PushDeer" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5292F4EC2776BC7900B9A7BB; + productRefGroup = 5292F4F62776BC7900B9A7BB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5292F4F42776BC7900B9A7BB /* PushDeer */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5292F4F32776BC7900B9A7BB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5292F5002776BC7A00B9A7BB /* Preview Assets.xcassets in Resources */, + 5292F4FD2776BC7A00B9A7BB /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5292F4F12776BC7900B9A7BB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52F0243F277737470071D861 /* LoginView.swift in Sources */, + 523150DC2778762B00941EDC /* DeviceItemView.swift in Sources */, + 523150D9277875FB00941EDC /* DeletableView.swift in Sources */, + 52163EBB277741AC00594190 /* SettingsView.swift in Sources */, + 52163EB327773F8400594190 /* MainView.swift in Sources */, + 52EB90B32778DA4E0048E0ED /* Line.swift in Sources */, + 52F2C223277961D7006F08DC /* SettingsItemView.swift in Sources */, + 52163EB72777415F00594190 /* DeviceListView.swift in Sources */, + 52163EB92777417900594190 /* KeyListView.swift in Sources */, + 5292F4FB2776BC7900B9A7BB /* ContentView.swift in Sources */, + 5292F4F92776BC7900B9A7BB /* PushDeerApp.swift in Sources */, + 52EB90AE2778AFD60048E0ED /* BaseNavigationView.swift in Sources */, + 52EB90AC2778ADF80048E0ED /* CardView.swift in Sources */, + 52EB90B02778D67F0048E0ED /* KeyItemView.swift in Sources */, + 52163EB52777413B00594190 /* MessageListView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 5292F5012776BC7A00B9A7BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 5292F5022776BC7A00B9A7BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5292F5042776BC7A00B9A7BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = PushDeer/PushDeer.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"PushDeer/Preview Content\""; + DEVELOPMENT_TEAM = Y47WTLML2S; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.wskfz.pushdeer.ios; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5292F5052776BC7A00B9A7BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = PushDeer/PushDeer.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"PushDeer/Preview Content\""; + DEVELOPMENT_TEAM = Y47WTLML2S; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.wskfz.pushdeer.ios; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5292F4F02776BC7900B9A7BB /* Build configuration list for PBXProject "PushDeer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5292F5012776BC7A00B9A7BB /* Debug */, + 5292F5022776BC7A00B9A7BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5292F5032776BC7A00B9A7BB /* Build configuration list for PBXNativeTarget "PushDeer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5292F5042776BC7A00B9A7BB /* Debug */, + 5292F5052776BC7A00B9A7BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5292F4ED2776BC7900B9A7BB /* Project object */; +} diff --git a/ios/PushDeer-iOS/PushDeer.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/PushDeer-iOS/PushDeer.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/PushDeer-iOS/PushDeer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/PushDeer-iOS/PushDeer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..7736646 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x89", + "green" : "0x47", + "red" : "0x3B" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Colors/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Colors/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Colors/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/Contents.json new file mode 100644 index 0000000..6ead5be --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "avatar1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "avatar1@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/avatar1.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/avatar1.png new file mode 100644 index 0000000..0d7cbb5 Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/avatar1.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/avatar1@2x.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/avatar1@2x.png new file mode 100644 index 0000000..f2540cf Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar1.imageset/avatar1@2x.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/Contents.json new file mode 100644 index 0000000..f77e25d --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "avatar2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "avatar2@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/avatar2.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/avatar2.png new file mode 100644 index 0000000..13ae66d Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/avatar2.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/avatar2@2x.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/avatar2@2x.png new file mode 100644 index 0000000..f6238fb Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/avatar2.imageset/avatar2@2x.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/Contents.json new file mode 100644 index 0000000..d12cc1a --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "deer.gray.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "deer.gray@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/deer.gray.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/deer.gray.png new file mode 100644 index 0000000..308d2d5 Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/deer.gray.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/deer.gray@2x.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/deer.gray@2x.png new file mode 100644 index 0000000..775bd52 Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/deer.gray.imageset/deer.gray@2x.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/Contents.json new file mode 100644 index 0000000..c1fd129 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "logo.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "logo@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/logo.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/logo.png new file mode 100644 index 0000000..06d3269 Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/logo.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/logo@2x.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/logo@2x.png new file mode 100644 index 0000000..30520e7 Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.imageset/logo@2x.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/Contents.json b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/Contents.json new file mode 100644 index 0000000..8d72d77 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "logo.with.space.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "logo.with.space@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/logo.with.space.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/logo.with.space.png new file mode 100644 index 0000000..4b7f1b4 Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/logo.with.space.png differ diff --git a/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/logo.with.space@2x.png b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/logo.with.space@2x.png new file mode 100644 index 0000000..1dad3f8 Binary files /dev/null and b/ios/PushDeer-iOS/PushDeer/Assets.xcassets/Images/logo.with.space.imageset/logo.with.space@2x.png differ diff --git a/ios/PushDeer-iOS/PushDeer/ContentView.swift b/ios/PushDeer-iOS/PushDeer/ContentView.swift new file mode 100644 index 0000000..13b6c27 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/ContentView.swift @@ -0,0 +1,21 @@ +// +// ContentView.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { +// LoginView() + MainView() + } +} + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} diff --git a/ios/PushDeer-iOS/PushDeer/Preview Content/Preview Assets.xcassets/Contents.json b/ios/PushDeer-iOS/PushDeer/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/PushDeer-iOS/PushDeer/PushDeer.entitlements b/ios/PushDeer-iOS/PushDeer/PushDeer.entitlements new file mode 100644 index 0000000..ee95ab7 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/PushDeer.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/ios/PushDeer-iOS/PushDeer/PushDeerApp.swift b/ios/PushDeer-iOS/PushDeer/PushDeerApp.swift new file mode 100644 index 0000000..b54ec1d --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/PushDeerApp.swift @@ -0,0 +1,17 @@ +// +// PushDeerApp.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI + +@main +struct PushDeerApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/Common/BaseNavigationView.swift b/ios/PushDeer-iOS/PushDeer/View/Common/BaseNavigationView.swift new file mode 100644 index 0000000..a808aeb --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/Common/BaseNavigationView.swift @@ -0,0 +1,40 @@ +// +// BaseNavigationView.swift +// PushDeer +// +// Created by HEXT on 2021/12/26. +// + +import SwiftUI + +/// 具有导航栏结构的基础容器View, APP内的页面基本上都可以使用它包装 +struct BaseNavigationView : View { + /// 导航栏标题 + let title: String + /// 页面主体View + @ViewBuilder let contentView: Content + + var body: some View { + NavigationView { + ZStack { + Spacer() + .frame(width: .infinity, height: .infinity) + contentView + } + .background( + Image("deer.gray").offset(x: -150, y: -10), + alignment: .bottom + ) + .navigationBarTitle(title) + } + .navigationViewStyle(.stack) + } +} + +struct BaseNavigationView_Previews: PreviewProvider { + static var previews: some View { + BaseNavigationView(title: "标题") { + Text("内容") + } + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/Common/CardView.swift b/ios/PushDeer-iOS/PushDeer/View/Common/CardView.swift new file mode 100644 index 0000000..3194a79 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/Common/CardView.swift @@ -0,0 +1,37 @@ +// +// CardView.swift +// PushDeer +// +// Created by HEXT on 2021/12/26. +// + +import SwiftUI + +/// 一个通用的卡片包装View +struct CardView : View { + /// 内容View + @ViewBuilder let contentView: Content + + var body: some View { + contentView + .overlay(RoundedRectangle(cornerRadius: 8).stroke()) + .foregroundColor(Color.accentColor) + .background( + Color(UIColor.systemBackground) + .cornerRadius(8) + .shadow( + color: Color.black.opacity(0.16), + radius: 6, x: 0, y: 3 + ) + ) + } +} + +struct CardView_Previews: PreviewProvider { + static var previews: some View { + CardView { + Text("Hello, World!") + .padding() + } + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/Common/DeletableView.swift b/ios/PushDeer-iOS/PushDeer/View/Common/DeletableView.swift new file mode 100644 index 0000000..17609fe --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/Common/DeletableView.swift @@ -0,0 +1,79 @@ +// +// DeletableView.swift +// PushDeer +// +// Created by HEXT on 2021/12/26. +// + +import SwiftUI + +/// 一个可左滑删除的包装View +struct DeletableView : View { + /// 内容View + @ViewBuilder let contentView: Content + /// 删除按钮点击的回调 + let deleteAction : () -> () + + /// 最大偏移 x, 可以认为是删除按钮漏出来的宽度 + private let offsetMaxX = 80.0 + + @State private var offsetX = 0.0 + @State private var isShowDelete = false + + var body: some View { + ZStack { + HStack { + Spacer() + Button(action: { + print("点击删除") + withAnimation(.easeOut) { + deleteAction() + } + }, label: { + Image(systemName: "trash") + .imageScale(.large) + .foregroundColor(Color.red) + .padding() + }) + } + contentView + .offset(x: offsetX, y: 0) + .gesture( + DragGesture() + .onChanged({ value in + let width = value.translation.width + print("onChanged", width) + let endX = isShowDelete ? offsetMaxX : 0.0 + if width < endX { + offsetX = width - endX + } else { + offsetX = 0 + } + }) + .onEnded({ value in + withAnimation(.easeOut) { + let width = value.translation.width + print("onEnded", width) + if width > -(offsetMaxX/2) { + offsetX = 0 + isShowDelete = false + } else { + offsetX = -offsetMaxX + isShowDelete = true + } + } + }) + ) + } + } +} + +struct DeletableView_Previews: PreviewProvider { + static var previews: some View { + DeletableView(contentView: { + DeviceItemView(name: "未知设备") + }, deleteAction: { + + }) + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/Common/Line.swift b/ios/PushDeer-iOS/PushDeer/View/Common/Line.swift new file mode 100644 index 0000000..fbbc899 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/Common/Line.swift @@ -0,0 +1,37 @@ +// +// Line.swift +// PushDeer +// +// Created by HEXT on 2021/12/27. +// + +import SwiftUI + +/// 水平线 +struct HLine: Shape { + func path(in rect: CGRect) -> Path { + Path { path in + path.move(to: CGPoint(x: rect.minX, y: rect.midY)) + path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY)) + } + } +} + +/// 垂直线 +struct VLine: Shape { + func path(in rect: CGRect) -> Path { + Path { path in + path.move(to: CGPoint(x: rect.midX, y: rect.minY)) + path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY)) + } + } +} + +struct Line_Previews: PreviewProvider { + static var previews: some View { + // 横虚线示例 + HLine().stroke(style: StrokeStyle(lineWidth: 1,dash: [5])) + // 竖实线 + VLine().stroke() + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/DeviceItemView.swift b/ios/PushDeer-iOS/PushDeer/View/DeviceItemView.swift new file mode 100644 index 0000000..fe7dfff --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/DeviceItemView.swift @@ -0,0 +1,34 @@ +// +// DeviceItemView.swift +// PushDeer +// +// Created by HEXT on 2021/12/26. +// + +import SwiftUI + +/// 每个设备项的 View +struct DeviceItemView: View { + var name: String + var body: some View { + CardView { + HStack{ + Image(systemName: "ipad.and.iphone") + .resizable() + .scaledToFit() + .frame(width: 40, height: 40, alignment: .center) + .padding(EdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 8)) + Text(name) + .font(.system(size: 20)) + Spacer() + } + .frame(height: 80) + } + } +} + +struct DeviceItemView_Previews: PreviewProvider { + static var previews: some View { + DeviceItemView(name: "未知设备") + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/DeviceListView.swift b/ios/PushDeer-iOS/PushDeer/View/DeviceListView.swift new file mode 100644 index 0000000..d67fd36 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/DeviceListView.swift @@ -0,0 +1,45 @@ +// +// DeviceListView.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI + +/// 设备界面 +struct DeviceListView: View { + @State var devices = Array(0..<10) + var body: some View { + BaseNavigationView(title: "设备") { + ScrollView { + LazyVStack(alignment: .center) { + ForEach(devices, id: \.self) { name in + DeletableView(contentView: { + DeviceItemView(name: "设备 \(name)") + }, deleteAction: { + devices.removeAll { _name in + _name == name + } + }) + .padding(EdgeInsets(top: 18, leading: 26, bottom: 0, trailing: 24)) + } + } + } + .navigationBarItems(trailing: Button(action: { + withAnimation(.easeOut) { + devices.insert(Int(arc4random_uniform(1000)), at: 0) + } + }, label: { + Image(systemName: "plus") + .foregroundColor(Color(UIColor.lightGray)) + })) + } + } +} + +struct DeviceView_Previews: PreviewProvider { + static var previews: some View { + DeviceListView() + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/KeyItemView.swift b/ios/PushDeer-iOS/PushDeer/View/KeyItemView.swift new file mode 100644 index 0000000..9245cf5 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/KeyItemView.swift @@ -0,0 +1,72 @@ +// +// KeyItemView.swift +// PushDeer +// +// Created by HEXT on 2021/12/27. +// + +import SwiftUI + +/// 每个 Key 项的 View +struct KeyItemView: View { + let keyItem: KeyItem + + var body: some View { + VStack(spacing: 20) { + HStack(alignment: .bottom) { + Image("avatar2") + .resizable() + .scaledToFit() + .frame(width: 38, height: 38) + Text("Key \(keyItem.id)") + .font(.system(size: 20)) + .foregroundColor(Color.accentColor) + Spacer() + Image(systemName: "calendar") + .font(.system(size: 14)) + .foregroundColor(Color.gray) + Text("2021/12/01") + .font(.system(size: 14)) + .foregroundColor(Color.gray) + } + + TextField("Key", text: .constant(keyItem.key) ) + .font(.system(size: 14)) + .disabled(true) + .padding(12) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color(UIColor.lightGray))) + .foregroundColor(Color.gray) + + HLine().stroke(Color.gray, style: StrokeStyle(lineWidth: 1, dash: [5])) + + HStack { + Button("重置") { + print("点击重置") + } + .font(.system(size: 20)) + .frame(width: 90, height: 42) + .overlay(RoundedRectangle(cornerRadius: 4).stroke()) + .foregroundColor(Color.accentColor) + + Spacer() + + Button("复制") { + print("点击复制") + UIPasteboard.general.string = keyItem.key + } + .font(.system(size: 20)) + .frame(width: 90, height: 42) + .foregroundColor(Color.white) + .background(Color.accentColor) + .cornerRadius(8) + } + } + .padding() + } +} + +struct KeyItemView_Previews: PreviewProvider { + static var previews: some View { + KeyItemView(keyItem: KeyItem(id: 1, key: "Key")) + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/KeyListView.swift b/ios/PushDeer-iOS/PushDeer/View/KeyListView.swift new file mode 100644 index 0000000..cbe289b --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/KeyListView.swift @@ -0,0 +1,59 @@ +// +// KeyListView.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI + +struct KeyItem: Codable, Identifiable{ + let id: Int + let key: String +} + +/// Key 界面 +struct KeyListView: View { + @State private var keyItems = [ + KeyItem(id: 1, key: UUID().uuidString), + KeyItem(id: 2, key: UUID().uuidString), + KeyItem(id: 3, key: UUID().uuidString), + KeyItem(id: 4, key: UUID().uuidString), + ] + var body: some View { + BaseNavigationView(title: "Key") { + ScrollView { + LazyVStack(alignment: .center) { + ForEach(keyItems) { keyItem in + DeletableView(contentView: { + CardView { + KeyItemView(keyItem: keyItem) + } + + }, deleteAction: { + keyItems.removeAll { _keyItem in + keyItem.id == _keyItem.id + } + }) + .padding(EdgeInsets(top: 18, leading: 26, bottom: 0, trailing: 24)) + } + } + } + .navigationBarItems(trailing: Button(action: { + let keyItem = KeyItem(id: Int(arc4random_uniform(1000)), key: UUID().uuidString) + withAnimation(.easeOut) { + keyItems.insert(keyItem, at: 0) + } + }, label: { + Image(systemName: "plus") + .foregroundColor(Color(UIColor.lightGray)) + })) + } + } +} + +struct KeyView_Previews: PreviewProvider { + static var previews: some View { + KeyListView() + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/LoginView.swift b/ios/PushDeer-iOS/PushDeer/View/LoginView.swift new file mode 100644 index 0000000..a8ea102 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/LoginView.swift @@ -0,0 +1,40 @@ +// +// LoginView.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI +import AuthenticationServices + +/// 登录界面 +struct LoginView: View { + var body: some View { + VStack{ + Spacer() + Image("logo.with.space") + .resizable() + .scaledToFit() + Spacer() + SignInWithAppleButton( + onRequest: { request in + + }, + onCompletion: { result in + + } + ) + .frame(height: 64) + .padding() + Spacer() + } + .padding() + } +} + +struct LoginView_Previews: PreviewProvider { + static var previews: some View { + LoginView() + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/MainView.swift b/ios/PushDeer-iOS/PushDeer/View/MainView.swift new file mode 100644 index 0000000..6fe1d89 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/MainView.swift @@ -0,0 +1,40 @@ +// +// MainView.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI + +/// APP 主界面 +struct MainView: View { + var body: some View { + TabView { + DeviceListView() + .tabItem { + Label("设备",systemImage: "ipad.and.iphone") + } + + KeyListView() + .tabItem{ + Label("Key",systemImage: "key") + } + + MessageListView() + .tabItem({Label("消息",systemImage: "message")}).onTapGesture { + } + + SettingsView() + .tabItem{ + Label("设置",systemImage: "gearshape") + } + } + } +} + +struct MainView_Previews: PreviewProvider { + static var previews: some View { + MainView() + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/MessageListView.swift b/ios/PushDeer-iOS/PushDeer/View/MessageListView.swift new file mode 100644 index 0000000..23f40fc --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/MessageListView.swift @@ -0,0 +1,21 @@ +// +// MessageListView.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI + +/// 消息界面 +struct MessageListView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +struct MessageView_Previews: PreviewProvider { + static var previews: some View { + MessageListView() + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/SettingsItemView.swift b/ios/PushDeer-iOS/PushDeer/View/SettingsItemView.swift new file mode 100644 index 0000000..b40ffd8 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/SettingsItemView.swift @@ -0,0 +1,45 @@ +// +// SettingsItemView.swift +// PushDeer +// +// Created by HeXiaoTian on 2021/12/27. +// + +import SwiftUI + +/// 每个设置项的 View +struct SettingsItemView: View { + let title: String + let button: String + let action: () -> () + var body: some View { + CardView { + HStack{ + Text(title) + .font(.system(size: 18)) + .foregroundColor(Color(UIColor.darkGray)) + .padding() + Spacer() + Button(button) { + print("点击\(button)") + action() + } + .font(.system(size: 20)) + .frame(width: 80, height: 42) + .foregroundColor(Color.white) + .background(Color.accentColor) + .cornerRadius(8) + .padding() + } + .frame(height: 74) + } + } +} + +struct SettingsItemView_Previews: PreviewProvider { + static var previews: some View { + SettingsItemView(title: "登录为 Hext", button: "退出") { + // logout + } + } +} diff --git a/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift b/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift new file mode 100644 index 0000000..8147033 --- /dev/null +++ b/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift @@ -0,0 +1,37 @@ +// +// SettingsView.swift +// PushDeer +// +// Created by HEXT on 2021/12/25. +// + +import SwiftUI + +/// 设置界面 +struct SettingsView: View { + var body: some View { + BaseNavigationView(title: "设置") { + VStack { + SettingsItemView(title: "登录为 Hext", button: "退出") { + } + .padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20)) + + SettingsItemView(title: "自定义服务器", button: "扫码") { + } + .padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20)) + + SettingsItemView(title: "喜欢PushDeer?", button: "评分") { + } + .padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20)) + + Spacer() + } + } + } +} + +struct SettingsView_Previews: PreviewProvider { + static var previews: some View { + SettingsView() + } +} diff --git a/ios/PushDeer-iOS/README.md b/ios/PushDeer-iOS/README.md new file mode 100644 index 0000000..2a6c062 --- /dev/null +++ b/ios/PushDeer-iOS/README.md @@ -0,0 +1,10 @@ +# PushDeer-iOS (开发中) + +PushDeer 是一个开放源码的无 App 推送服务. + +这里是 PushDeer 的 iOS 端的源码, 支持 iOS / iPadOS / macOS. + + +PushDeer-iOS 最低支持 iOS14, 因为苹果轻应用(App Clips)最低支持 iOS14. + +由于苹果规定轻应用必须随 APP 一起发布, 所以除了扫码打开轻应用即时享用推送服务, 实际上你也可以下载 APP 使用. \ No newline at end of file