From b2d0c77a45d00e2f311d99f9b3a15ed6613b5d92 Mon Sep 17 00:00:00 2001 From: zhaixian Date: Fri, 1 Mar 2024 16:51:51 +0800 Subject: [PATCH] feat: modify the authorization and the command, support visionOS (#43) --- AliyunpanSDK.podspec | 1 + AliyunpanSDK.xcodeproj/project.pbxproj | 18 +- Demo/Demo.xcodeproj/project.pbxproj | 237 +++++++++++++++++- Demo/Demo/Client.swift | 17 ++ Demo/Demo/Demo-MacOS/AppDelegate.swift | 4 +- .../Demo-MacOS/ExamplesViewController.swift | 29 +-- Demo/Demo/Demo-MacOS/ViewController.swift | 17 +- Demo/Demo/Demo-iOS/AppDelegate.swift | 6 - .../Demo-iOS/FileListViewController.swift | 38 +-- Demo/Demo/Demo-iOS/ViewController.swift | 88 ++++--- .../Content.imageset/Contents.json | 12 + .../Back.solidimagestacklayer/Contents.json | 6 + .../AppIcon.solidimagestack/Contents.json | 17 ++ .../Content.imageset/Contents.json | 12 + .../Front.solidimagestacklayer/Contents.json | 6 + .../Content.imageset/Contents.json | 12 + .../Middle.solidimagestacklayer/Contents.json | 6 + .../Assets.xcassets/Contents.json | 6 + Demo/Demo/Demo-visionOS/ContentView.swift | 82 ++++++ .../Demo/Demo-visionOS/Demo_visionOSApp.swift | 17 ++ Demo/Demo/Demo-visionOS/Info.plist | 15 ++ .../Preview Assets.xcassets/Contents.json | 6 + Demo/Podfile.lock | 6 +- Demo/podfile | 5 + Package.swift | 17 +- Package@swift-5.9.swift | 30 +++ README.md | 49 ++-- Sources/AliyunpanSDK/AliyunpanClient.swift | 47 ++-- .../Vip/GetVipFeatureList.swift | 2 +- .../Download/AliyunpanDownloader.swift | 8 +- .../AliyunpanClientTests.swift | 6 +- 31 files changed, 659 insertions(+), 163 deletions(-) create mode 100644 Demo/Demo/Client.swift create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/Assets.xcassets/Contents.json create mode 100644 Demo/Demo/Demo-visionOS/ContentView.swift create mode 100644 Demo/Demo/Demo-visionOS/Demo_visionOSApp.swift create mode 100644 Demo/Demo/Demo-visionOS/Info.plist create mode 100644 Demo/Demo/Demo-visionOS/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 Package@swift-5.9.swift diff --git a/AliyunpanSDK.podspec b/AliyunpanSDK.podspec index dd4f6ff..98c11b6 100644 --- a/AliyunpanSDK.podspec +++ b/AliyunpanSDK.podspec @@ -15,6 +15,7 @@ Pod::Spec.new do |spec| spec.ios.deployment_target = "13.0" spec.tvos.deployment_target = "13.0" spec.osx.deployment_target = "10.15" + spec.visionos.deployment_target = "1.0" spec.source = { :git => "https://github.com/alibaba/aliyunpan-ios-sdk.git", :tag => "v#{spec.version}" } diff --git a/AliyunpanSDK.xcodeproj/project.pbxproj b/AliyunpanSDK.xcodeproj/project.pbxproj index 06e00c7..f30bd1a 100644 --- a/AliyunpanSDK.xcodeproj/project.pbxproj +++ b/AliyunpanSDK.xcodeproj/project.pbxproj @@ -703,6 +703,7 @@ TVOS_DEPLOYMENT_TARGET = 13.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + XROS_DEPLOYMENT_TARGET = 1.0; }; name = Debug; }; @@ -762,6 +763,7 @@ TVOS_DEPLOYMENT_TARGET = 13.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + XROS_DEPLOYMENT_TARGET = 1.0; }; name = Release; }; @@ -803,12 +805,12 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = ""; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvos appletvsimulator macosx"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3"; + TARGETED_DEVICE_FAMILY = "1,2,3,7"; }; name = Debug; }; @@ -851,18 +853,19 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = ""; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvos appletvsimulator macosx"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3"; + TARGETED_DEVICE_FAMILY = "1,2,3,7"; }; name = Release; }; F4C6F23E2B060C4B003A06B3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; @@ -880,7 +883,8 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = ""; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvos appletvsimulator macosx"; + SUPPORTED_PLATFORMS = "xrsimulator xros watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; @@ -892,6 +896,7 @@ F4C6F23F2B060C4B003A06B3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; @@ -909,7 +914,8 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = ""; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvos appletvsimulator macosx"; + SUPPORTED_PLATFORMS = "xrsimulator xros watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; diff --git a/Demo/Demo.xcodeproj/project.pbxproj b/Demo/Demo.xcodeproj/project.pbxproj index 39bee66..c0cd119 100644 --- a/Demo/Demo.xcodeproj/project.pbxproj +++ b/Demo/Demo.xcodeproj/project.pbxproj @@ -9,7 +9,17 @@ /* Begin PBXBuildFile section */ 5EDF091C4AF354E5DF87DDD8 /* Pods_Demo_TVOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DFF34E0FF70A4CA1AACBF97B /* Pods_Demo_TVOS.framework */; }; 800CDB91F44F3ABF59C0CF1C /* Pods_Demo_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB0896F019B0892FD9D400C0 /* Pods_Demo_iOS.framework */; }; + 9AAA9ACAB712BC3C1E8916B1 /* Pods_Demo_visionOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAF6BAD0F13CF81250806A40 /* Pods_Demo_visionOS.framework */; }; C38E4C7A90D3B4101AE86EA7 /* Pods_Demo_MacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54114E3E18039C35C071F406 /* Pods_Demo_MacOS.framework */; }; + F42398B82B8356D300ACC723 /* RealityKitContent in Frameworks */ = {isa = PBXBuildFile; productRef = F42398B72B8356D300ACC723 /* RealityKitContent */; }; + F42398BA2B8356D300ACC723 /* Demo_visionOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42398B92B8356D300ACC723 /* Demo_visionOSApp.swift */; }; + F42398BC2B8356D300ACC723 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42398BB2B8356D300ACC723 /* ContentView.swift */; }; + F42398BE2B8356D400ACC723 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F42398BD2B8356D400ACC723 /* Assets.xcassets */; }; + F42398C12B8356D400ACC723 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F42398C02B8356D400ACC723 /* Preview Assets.xcassets */; }; + F42398CA2B847B2600ACC723 /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42398C92B847B2600ACC723 /* Client.swift */; }; + F42398CB2B847B2600ACC723 /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42398C92B847B2600ACC723 /* Client.swift */; }; + F42398CC2B847B2600ACC723 /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42398C92B847B2600ACC723 /* Client.swift */; }; + F42398CD2B847B2600ACC723 /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42398C92B847B2600ACC723 /* Client.swift */; }; F4BD1BF82B29AA99002BEA2A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4BD1BDB2B29AA99002BEA2A /* ViewController.swift */; }; F4BD1BFB2B29AA99002BEA2A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4BD1BDC2B29AA99002BEA2A /* Assets.xcassets */; }; F4BD1BFE2B29AA99002BEA2A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F4BD1BDD2B29AA99002BEA2A /* LaunchScreen.storyboard */; }; @@ -41,13 +51,24 @@ 3BD09E68C07B0C8E71B045AE /* Pods-Demo-MacOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo-MacOS.debug.xcconfig"; path = "Target Support Files/Pods-Demo-MacOS/Pods-Demo-MacOS.debug.xcconfig"; sourceTree = ""; }; 4088A4FEEAABF0D1A7BEAA5A /* Pods-Demo-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo-iOS.release.xcconfig"; path = "Target Support Files/Pods-Demo-iOS/Pods-Demo-iOS.release.xcconfig"; sourceTree = ""; }; 54114E3E18039C35C071F406 /* Pods_Demo_MacOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Demo_MacOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E0E3EEBD4DB7842D52A62CE /* Pods-Demo-visionOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo-visionOS.debug.xcconfig"; path = "Target Support Files/Pods-Demo-visionOS/Pods-Demo-visionOS.debug.xcconfig"; sourceTree = ""; }; 85D74B78D3E8A4C3E655AC9E /* Pods-Demo-TVOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo-TVOS.release.xcconfig"; path = "Target Support Files/Pods-Demo-TVOS/Pods-Demo-TVOS.release.xcconfig"; sourceTree = ""; }; 95FE364CDD4607AF4CCC6B91 /* Pods-Demo-TVOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo-TVOS.debug.xcconfig"; path = "Target Support Files/Pods-Demo-TVOS/Pods-Demo-TVOS.debug.xcconfig"; sourceTree = ""; }; 9CAE1A0A2DB08870265E86AE /* Pods-Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo.debug.xcconfig"; path = "Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig"; sourceTree = ""; }; + ADDCA491B1F0D32F4760F58D /* Pods-Demo-visionOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo-visionOS.release.xcconfig"; path = "Target Support Files/Pods-Demo-visionOS/Pods-Demo-visionOS.release.xcconfig"; sourceTree = ""; }; AFA546012E2373B08060C87B /* Pods-Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo.release.xcconfig"; path = "Target Support Files/Pods-Demo/Pods-Demo.release.xcconfig"; sourceTree = ""; }; + DAF6BAD0F13CF81250806A40 /* Pods_Demo_visionOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Demo_visionOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DB0896F019B0892FD9D400C0 /* Pods_Demo_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Demo_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DFF34E0FF70A4CA1AACBF97B /* Pods_Demo_TVOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Demo_TVOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E30F77603B1724FF4ED3A5CF /* Pods-Demo-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo-iOS.debug.xcconfig"; path = "Target Support Files/Pods-Demo-iOS/Pods-Demo-iOS.debug.xcconfig"; sourceTree = ""; }; + F42398A12B83569C00ACC723 /* RealityKitContent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = RealityKitContent; sourceTree = ""; }; + F42398B52B8356D300ACC723 /* Demo-visionOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Demo-visionOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + F42398B92B8356D300ACC723 /* Demo_visionOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Demo_visionOSApp.swift; sourceTree = ""; }; + F42398BB2B8356D300ACC723 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + F42398BD2B8356D400ACC723 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + F42398C02B8356D400ACC723 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + F42398C22B8356D400ACC723 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F42398C92B847B2600ACC723 /* Client.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Client.swift; sourceTree = ""; }; F4BD1BB52B29AA15002BEA2A /* Demo-MacOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Demo-MacOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; F4BD1BC82B29AA7E002BEA2A /* Demo-TVOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Demo-TVOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; F4BD1BDB2B29AA99002BEA2A /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -77,6 +98,15 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + F42398B22B8356D300ACC723 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F42398B82B8356D300ACC723 /* RealityKitContent in Frameworks */, + 9AAA9ACAB712BC3C1E8916B1 /* Pods_Demo_visionOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F4BD1BB22B29AA15002BEA2A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -115,18 +145,50 @@ 4088A4FEEAABF0D1A7BEAA5A /* Pods-Demo-iOS.release.xcconfig */, 95FE364CDD4607AF4CCC6B91 /* Pods-Demo-TVOS.debug.xcconfig */, 85D74B78D3E8A4C3E655AC9E /* Pods-Demo-TVOS.release.xcconfig */, + 5E0E3EEBD4DB7842D52A62CE /* Pods-Demo-visionOS.debug.xcconfig */, + ADDCA491B1F0D32F4760F58D /* Pods-Demo-visionOS.release.xcconfig */, ); path = Pods; sourceTree = ""; }; + F42398A02B83569C00ACC723 /* Packages */ = { + isa = PBXGroup; + children = ( + F42398A12B83569C00ACC723 /* RealityKitContent */, + ); + path = Packages; + sourceTree = ""; + }; + F42398B62B8356D300ACC723 /* Demo-visionOS */ = { + isa = PBXGroup; + children = ( + F42398B92B8356D300ACC723 /* Demo_visionOSApp.swift */, + F42398BB2B8356D300ACC723 /* ContentView.swift */, + F42398BD2B8356D400ACC723 /* Assets.xcassets */, + F42398C22B8356D400ACC723 /* Info.plist */, + F42398BF2B8356D400ACC723 /* Preview Content */, + ); + path = "Demo-visionOS"; + sourceTree = ""; + }; + F42398BF2B8356D400ACC723 /* Preview Content */ = { + isa = PBXGroup; + children = ( + F42398C02B8356D400ACC723 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; F4BD1BD92B29AA99002BEA2A /* Demo */ = { isa = PBXGroup; children = ( F4BD1C3B2B2C45C6002BEA2A /* Example.swift */, F4BD1BEB2B29AA99002BEA2A /* DisplayItem.swift */, + F42398C92B847B2600ACC723 /* Client.swift */, F4BD1BE22B29AA99002BEA2A /* Demo-iOS */, F4BD1BEF2B29AA99002BEA2A /* Demo-MacOS */, F4BD1BDA2B29AA99002BEA2A /* Demo-TVOS */, + F42398B62B8356D300ACC723 /* Demo-visionOS */, ); path = Demo; sourceTree = ""; @@ -176,6 +238,7 @@ isa = PBXGroup; children = ( F4BD1BD92B29AA99002BEA2A /* Demo */, + F42398A02B83569C00ACC723 /* Packages */, F4E3E5422B0F41580041AE19 /* Products */, F4E3E5612B0F41930041AE19 /* Frameworks */, 15BE5812909D76A268E3810E /* Pods */, @@ -188,6 +251,7 @@ F4E3E5412B0F41580041AE19 /* Demo-iOS.app */, F4BD1BB52B29AA15002BEA2A /* Demo-MacOS.app */, F4BD1BC82B29AA7E002BEA2A /* Demo-TVOS.app */, + F42398B52B8356D300ACC723 /* Demo-visionOS.app */, ); name = Products; sourceTree = ""; @@ -199,6 +263,7 @@ 54114E3E18039C35C071F406 /* Pods_Demo_MacOS.framework */, DB0896F019B0892FD9D400C0 /* Pods_Demo_iOS.framework */, DFF34E0FF70A4CA1AACBF97B /* Pods_Demo_TVOS.framework */, + DAF6BAD0F13CF81250806A40 /* Pods_Demo_visionOS.framework */, ); name = Frameworks; sourceTree = ""; @@ -206,6 +271,28 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + F42398B42B8356D300ACC723 /* Demo-visionOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = F42398C32B8356D400ACC723 /* Build configuration list for PBXNativeTarget "Demo-visionOS" */; + buildPhases = ( + EBA68EDEEBE5219C83118B91 /* [CP] Check Pods Manifest.lock */, + F42398B12B8356D300ACC723 /* Sources */, + F42398B22B8356D300ACC723 /* Frameworks */, + F42398B32B8356D300ACC723 /* Resources */, + 80670B1C404FA941EE004070 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Demo-visionOS"; + packageProductDependencies = ( + F42398B72B8356D300ACC723 /* RealityKitContent */, + ); + productName = "Demo-visionOS"; + productReference = F42398B52B8356D300ACC723 /* Demo-visionOS.app */; + productType = "com.apple.product-type.application"; + }; F4BD1BB42B29AA15002BEA2A /* Demo-MacOS */ = { isa = PBXNativeTarget; buildConfigurationList = F4BD1BC12B29AA16002BEA2A /* Build configuration list for PBXNativeTarget "Demo-MacOS" */; @@ -270,9 +357,12 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1430; + LastSwiftUpdateCheck = 1520; LastUpgradeCheck = 1430; TargetAttributes = { + F42398B42B8356D300ACC723 = { + CreatedOnToolsVersion = 15.2; + }; F4BD1BB42B29AA15002BEA2A = { CreatedOnToolsVersion = 14.3.1; }; @@ -301,11 +391,21 @@ F4E3E5402B0F41580041AE19 /* Demo-iOS */, F4BD1BB42B29AA15002BEA2A /* Demo-MacOS */, F4BD1BC72B29AA7E002BEA2A /* Demo-TVOS */, + F42398B42B8356D300ACC723 /* Demo-visionOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + F42398B32B8356D300ACC723 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F42398C12B8356D400ACC723 /* Preview Assets.xcassets in Resources */, + F42398BE2B8356D400ACC723 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F4BD1BB32B29AA15002BEA2A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -394,6 +494,23 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Demo-MacOS/Pods-Demo-MacOS-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 80670B1C404FA941EE004070 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Demo-visionOS/Pods-Demo-visionOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Demo-visionOS/Pods-Demo-visionOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Demo-visionOS/Pods-Demo-visionOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; CD39C88B468CEB37B6CF39BF /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -433,6 +550,28 @@ 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; }; + EBA68EDEEBE5219C83118B91 /* [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-Demo-visionOS-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; + }; F744034AA96306D8C7E95384 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -458,12 +597,23 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + F42398B12B8356D300ACC723 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F42398BC2B8356D300ACC723 /* ContentView.swift in Sources */, + F42398BA2B8356D300ACC723 /* Demo_visionOSApp.swift in Sources */, + F42398CD2B847B2600ACC723 /* Client.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F4BD1BB12B29AA15002BEA2A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F4BD1C242B29AA99002BEA2A /* ViewController.swift in Sources */, F4BD1C3A2B2C270A002BEA2A /* ExamplesViewController.swift in Sources */, + F42398CB2B847B2600ACC723 /* Client.swift in Sources */, F4BD1C2D2B29AA99002BEA2A /* AppDelegate.swift in Sources */, F4BD1C2F2B29B329002BEA2A /* DisplayItem.swift in Sources */, F4BD1C3C2B2C45C6002BEA2A /* Example.swift in Sources */, @@ -477,6 +627,7 @@ F4BD1C3E2B2C45D7002BEA2A /* Example.swift in Sources */, F4BD1C042B29AA99002BEA2A /* AppDelegate.swift in Sources */, F4BD1BF82B29AA99002BEA2A /* ViewController.swift in Sources */, + F42398CC2B847B2600ACC723 /* Client.swift in Sources */, F4BD1C302B29B32A002BEA2A /* DisplayItem.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -491,6 +642,7 @@ F4BD1C082B29AA99002BEA2A /* ViewController.swift in Sources */, F4BD1C1A2B29AA99002BEA2A /* AppDelegate.swift in Sources */, F4BD1C172B29AA99002BEA2A /* DisplayItem.swift in Sources */, + F42398CA2B847B2600ACC723 /* Client.swift in Sources */, F4BD1C202B29AA99002BEA2A /* SceneDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -541,6 +693,73 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + F42398C42B8356D400ACC723 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5E0E3EEBD4DB7842D52A62CE /* Pods-Demo-visionOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Demo/Demo-visionOS/Preview Content\""; + DEVELOPMENT_TEAM = 94F2JS8SWX; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Demo/$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.smartdrive.Demo-visionOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; + }; + name = Debug; + }; + F42398C52B8356D400ACC723 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = ADDCA491B1F0D32F4760F58D /* Pods-Demo-visionOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Demo/Demo-visionOS/Preview Content\""; + DEVELOPMENT_TEAM = 94F2JS8SWX; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Demo/$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.smartdrive.Demo-visionOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.0; + }; + name = Release; + }; F4BD1BC22B29AA16002BEA2A /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3BD09E68C07B0C8E71B045AE /* Pods-Demo-MacOS.debug.xcconfig */; @@ -845,6 +1064,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + F42398C32B8356D400ACC723 /* Build configuration list for PBXNativeTarget "Demo-visionOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F42398C42B8356D400ACC723 /* Debug */, + F42398C52B8356D400ACC723 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; F4BD1BC12B29AA16002BEA2A /* Build configuration list for PBXNativeTarget "Demo-MacOS" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -882,6 +1110,13 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + F42398B72B8356D300ACC723 /* RealityKitContent */ = { + isa = XCSwiftPackageProductDependency; + productName = RealityKitContent; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = F4E3E5392B0F41580041AE19 /* Project object */; } diff --git a/Demo/Demo/Client.swift b/Demo/Demo/Client.swift new file mode 100644 index 0000000..aae8e52 --- /dev/null +++ b/Demo/Demo/Client.swift @@ -0,0 +1,17 @@ +// +// Client.swift +// Demo +// +// Created by zhaixian on 2024/2/20. +// + +import Foundation +import AliyunpanSDK + +let appId = "YOUR_APP_ID" // 替换成你的 AppID +let scope = "user:base,file:all:read,file:all:write" + +let client = AliyunpanClient( + appId: appId, + scope: scope +) diff --git a/Demo/Demo/Demo-MacOS/AppDelegate.swift b/Demo/Demo/Demo-MacOS/AppDelegate.swift index c7b8702..03223af 100644 --- a/Demo/Demo/Demo-MacOS/AppDelegate.swift +++ b/Demo/Demo/Demo-MacOS/AppDelegate.swift @@ -9,9 +9,7 @@ import Cocoa import AliyunpanSDK @main -class AppDelegate: NSObject, NSApplicationDelegate { - var client: AliyunpanClient? - +class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { Aliyunpan.setLogLevel(.info) } diff --git a/Demo/Demo/Demo-MacOS/ExamplesViewController.swift b/Demo/Demo/Demo-MacOS/ExamplesViewController.swift index 2a93f9e..73ad333 100644 --- a/Demo/Demo/Demo-MacOS/ExamplesViewController.swift +++ b/Demo/Demo/Demo-MacOS/ExamplesViewController.swift @@ -13,10 +13,6 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi let examples = Example.allCases - var client: AliyunpanClient? { - (NSApplication.shared.delegate as! AppDelegate).client - } - override func viewDidLoad() { super.viewDidLoad() @@ -39,9 +35,6 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi } func tableViewSelectionDidChange(_ notification: Notification) { - guard let client else { - return - } // 当选中的行发生变化时被调用 let selectedRow = tableView.selectedRow @@ -54,7 +47,7 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi case .getUserInfo: Task { do { - let vipInfo = try await client.send(AliyunpanScope.User.GetUsersInfo()) + let vipInfo = try await client.authorize().send(AliyunpanScope.User.GetUsersInfo()) showAlert(message: String(describing: vipInfo)) } catch { showAlert(message: String(describing: error)) @@ -63,7 +56,7 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi case .getDriveInfo: Task { do { - let vipInfo = try await client.send(AliyunpanScope.User.GetDriveInfo()) + let vipInfo = try await client.authorize().send(AliyunpanScope.User.GetDriveInfo()) showAlert(message: String(describing: vipInfo)) } catch { showAlert(message: String(describing: error)) @@ -72,7 +65,7 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi case .getSpaceInfo: Task { do { - let vipInfo = try await client.send(AliyunpanScope.User.GetSpaceInfo()) + let vipInfo = try await client.authorize().send(AliyunpanScope.User.GetSpaceInfo()) showAlert(message: String(describing: vipInfo)) } catch { showAlert(message: String(describing: error)) @@ -81,7 +74,7 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi case .getVIPInfo: Task { do { - let vipInfo = try await client.send(AliyunpanScope.User.GetVipInfo()) + let vipInfo = try await client.authorize().send(AliyunpanScope.User.GetVipInfo()) showAlert(message: String(describing: vipInfo)) } catch { showAlert(message: String(describing: error)) @@ -90,7 +83,7 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi case .getVipFeatureList: Task { do { - let featureList = try await client.send(AliyunpanScope.VIP.GetVipFeatureList()) + let featureList = try await client.authorize().send(AliyunpanScope.VIP.GetVipFeatureList()) showAlert(message: String(describing: featureList)) } catch { showAlert(message: String(describing: error)) @@ -98,11 +91,11 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi } case .fetchFileList: Task { - let driveInfo = try await client.send(AliyunpanScope.User.GetDriveInfo()) + let driveInfo = try await client.authorize().send(AliyunpanScope.User.GetDriveInfo()) let driveId = driveInfo.default_drive_id - let fileList = try await client.send(AliyunpanScope.File.GetFileList(.init(drive_id: driveId, parent_file_id: "root"))).items + let fileList = try await client.authorize().send(AliyunpanScope.File.GetFileList(.init(drive_id: driveId, parent_file_id: "root"))).items showFileDetailViewController(files: fileList) } @@ -111,11 +104,11 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi case .createFolderOnRoot: Task { do { - let driveInfo = try await client.send(AliyunpanScope.User.GetDriveInfo()) + let driveInfo = try await client.authorize().send(AliyunpanScope.User.GetDriveInfo()) let driveId = driveInfo.default_drive_id - let response = try await client.send( + let response = try await client.authorize().send( AliyunpanScope.File.CreateFile( .init( drive_id: driveId, @@ -158,10 +151,6 @@ class ExamplesViewController: NSViewController, NSTableViewDataSource, NSTableVi } class DetailViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { - var client: AliyunpanClient? { - (NSApplication.shared.delegate as! AppDelegate).client - } - var files: [AliyunpanFile] = [] var parentDetailViewController: DetailViewController? diff --git a/Demo/Demo/Demo-MacOS/ViewController.swift b/Demo/Demo/Demo-MacOS/ViewController.swift index 995fb24..5fec6c5 100644 --- a/Demo/Demo/Demo-MacOS/ViewController.swift +++ b/Demo/Demo/Demo-MacOS/ViewController.swift @@ -8,24 +8,12 @@ import Cocoa import AliyunpanSDK -class ViewController: NSViewController { - private lazy var client: AliyunpanClient = { - let client = AliyunpanClient( - .init( - appId: "YOUR_APP_ID", // 替换成你的 AppID - scope: "user:base,file:all:read,file:all:write", - credentials: .qrCode(self))) - return client - }() - +class ViewController: NSViewController { private var authorizeButton = NSButton() private var imageView = NSImageView() override func viewDidLoad() { super.viewDidLoad() - - (NSApplication.shared.delegate as! AppDelegate).client = client - authorizeButton.title = "Authorize" authorizeButton.bezelStyle = .roundRect view.addSubview(authorizeButton) @@ -60,7 +48,8 @@ class ViewController: NSViewController { @objc private func showQRCode() { Task { do { - try await client.authorize() + try await client.authorize( + credentials: .qrCode(self)) } catch { print(error) } diff --git a/Demo/Demo/Demo-iOS/AppDelegate.swift b/Demo/Demo/Demo-iOS/AppDelegate.swift index a471c5c..6aef8ae 100644 --- a/Demo/Demo/Demo-iOS/AppDelegate.swift +++ b/Demo/Demo/Demo-iOS/AppDelegate.swift @@ -10,12 +10,6 @@ import AliyunpanSDK @main class AppDelegate: UIResponder, UIApplicationDelegate { - let client = AliyunpanClient( - .init( - appId: "YOUR_APP_ID", // 替换成你的 AppID - scope: "user:base,file:all:read,file:all:write", - credentials: .pkce)) - func applicationDidFinishLaunching(_ application: UIApplication) { Aliyunpan.setLogLevel(.info) } diff --git a/Demo/Demo/Demo-iOS/FileListViewController.swift b/Demo/Demo/Demo-iOS/FileListViewController.swift index d139ad3..dc1094e 100644 --- a/Demo/Demo/Demo-iOS/FileListViewController.swift +++ b/Demo/Demo/Demo-iOS/FileListViewController.swift @@ -15,13 +15,6 @@ class FileListViewController: UIViewController { label.font = UIFont.monospacedSystemFont(ofSize: 12, weight: .regular) return label }() - - private lazy var client: AliyunpanClient = { - let client = (UIApplication.shared.delegate as! AppDelegate).client - client.downloader.addDelegate(self) - client.downloader.enableNetworkSpeedMonitor() - return client - }() private lazy var dataSource: UICollectionViewDiffableDataSource = { let cellRegistration = UICollectionView.CellRegistration { [weak self] cell, _, item in @@ -75,6 +68,9 @@ class FileListViewController: UIViewController { snapshot.appendSections([0]) snapshot.appendItems(displayItems) dataSource.apply(snapshot) + + client.downloader.addDelegate(self) + client.downloader.enableNetworkSpeedMonitor() } /// 播放音频 @@ -99,7 +95,9 @@ class FileListViewController: UIViewController { @MainActor private func navigateToFolder(_ folder: AliyunpanFile) { Task { - let files = try await client.send(AliyunpanScope.File.GetFileList( + let files = try await client + .authorize() + .send(AliyunpanScope.File.GetFileList( .init(drive_id: folder.drive_id, parent_file_id: folder.file_id))) .items @@ -126,11 +124,13 @@ extension FileListViewController: UICollectionViewDelegate { case .video: Task { do { - let playInfo = try await self.client.send( - AliyunpanScope.Video.GetVideoPreviewPlayInfo( - .init( - drive_id: file.drive_id, - file_id: file.file_id))) + let playInfo = try await client + .authorize() + .send( + AliyunpanScope.Video.GetVideoPreviewPlayInfo( + .init( + drive_id: file.drive_id, + file_id: file.file_id))) /// 获取画质最高的已转码播放链接 let playURL = playInfo.video_preview_play_info.live_transcoding_task_list @@ -149,11 +149,13 @@ extension FileListViewController: UICollectionViewDelegate { Task { do { /// 目前音频需要使用 download url 播放 - let playURL = try await self.client.send( - AliyunpanScope.File.GetFileDownloadUrl( - .init( - drive_id: file.drive_id, - file_id: file.file_id))).url + let playURL = try await client + .authorize() + .send( + AliyunpanScope.File.GetFileDownloadUrl( + .init( + drive_id: file.drive_id, + file_id: file.file_id))).url playMedia(playURL) } catch { print(error) diff --git a/Demo/Demo/Demo-iOS/ViewController.swift b/Demo/Demo/Demo-iOS/ViewController.swift index 71cfa66..c29504a 100644 --- a/Demo/Demo/Demo-iOS/ViewController.swift +++ b/Demo/Demo/Demo-iOS/ViewController.swift @@ -9,10 +9,6 @@ import UIKit import AliyunpanSDK class ViewController: UIViewController { - private var client: AliyunpanClient { - (UIApplication.shared.delegate as! AppDelegate).client - } - private let activityIndicatorView: UIActivityIndicatorView = { let activityIndicatorView = UIActivityIndicatorView(style: .medium) activityIndicatorView.hidesWhenStopped = true @@ -73,17 +69,21 @@ class ViewController: UIViewController { /// https://www.yuque.com/aliyundrive/zpfszx/ezlzok#C8JdZ Task { do { - let driveInfo = try await self.client.send(AliyunpanScope.User.GetDriveInfo()) + let driveInfo = try await client + .authorize() + .send(AliyunpanScope.User.GetDriveInfo()) let driveId = driveInfo.default_drive_id - let response = try await self.client.send( - AliyunpanScope.File.CreateFile( - .init( - drive_id: driveId, - parent_file_id: "root", - name: url.lastPathComponent, - check_name_mode: .auto_rename))) + let response = try await client + .authorize() + .send( + AliyunpanScope.File.CreateFile( + .init( + drive_id: driveId, + parent_file_id: "root", + name: url.lastPathComponent, + check_name_mode: .auto_rename))) if let uploadURL = response.part_info_list?.first?.upload_url { var urlRequest = URLRequest(url: uploadURL) @@ -93,12 +93,14 @@ class ViewController: UIViewController { ] _ = try await URLSession.shared.upload(for: urlRequest, fromFile: url) - let file = try await self.client.send( - AliyunpanScope.File.CompleteUpload( - .init( - drive_id: driveId, - file_id: response.file_id, - upload_id: response.upload_id ?? ""))) + let file = try await client + .authorize() + .send( + AliyunpanScope.File.CompleteUpload( + .init( + drive_id: driveId, + file_id: response.file_id, + upload_id: response.upload_id ?? ""))) showAlert(message: file.description) } @@ -120,7 +122,9 @@ extension ViewController: UICollectionViewDelegate { Task { do { activityIndicatorView.startAnimating() - let vipInfo = try await client.send(AliyunpanScope.User.GetUsersInfo()) + let vipInfo = try await client + .authorize() + .send(AliyunpanScope.User.GetUsersInfo()) showAlert(message: String(describing: vipInfo)) activityIndicatorView.stopAnimating() } catch { @@ -131,7 +135,9 @@ extension ViewController: UICollectionViewDelegate { Task { do { activityIndicatorView.startAnimating() - let vipInfo = try await client.send(AliyunpanScope.User.GetDriveInfo()) + let vipInfo = try await client + .authorize() + .send(AliyunpanScope.User.GetDriveInfo()) showAlert(message: String(describing: vipInfo)) activityIndicatorView.stopAnimating() } catch { @@ -142,7 +148,9 @@ extension ViewController: UICollectionViewDelegate { Task { do { activityIndicatorView.startAnimating() - let vipInfo = try await client.send(AliyunpanScope.User.GetSpaceInfo()) + let vipInfo = try await client + .authorize() + .send(AliyunpanScope.User.GetSpaceInfo()) showAlert(message: String(describing: vipInfo)) activityIndicatorView.stopAnimating() } catch { @@ -153,7 +161,9 @@ extension ViewController: UICollectionViewDelegate { Task { do { activityIndicatorView.startAnimating() - let vipInfo = try await client.send(AliyunpanScope.User.GetVipInfo()) + let vipInfo = try await client + .authorize() + .send(AliyunpanScope.User.GetVipInfo()) showAlert(message: String(describing: vipInfo)) activityIndicatorView.stopAnimating() } catch { @@ -164,7 +174,9 @@ extension ViewController: UICollectionViewDelegate { Task { do { activityIndicatorView.startAnimating() - let featureList = try await client.send(AliyunpanScope.VIP.GetVipFeatureList()) + let featureList = try await client + .authorize() + .send(AliyunpanScope.VIP.GetVipFeatureList()) showAlert(message: String(describing: featureList)) activityIndicatorView.stopAnimating() } catch { @@ -175,11 +187,15 @@ extension ViewController: UICollectionViewDelegate { Task { do { activityIndicatorView.startAnimating() - let driveInfo = try await client.send(AliyunpanScope.User.GetDriveInfo()) + let driveInfo = try await client + .authorize() + .send(AliyunpanScope.User.GetDriveInfo()) let driveId = driveInfo.default_drive_id - let fileList = try await client.send(AliyunpanScope.File.GetFileList(.init(drive_id: driveId, parent_file_id: "root"))) + let fileList = try await client + .authorize() + .send(AliyunpanScope.File.GetFileList(.init(drive_id: driveId, parent_file_id: "root"))) let vc = FileListViewController() vc.files = fileList.items @@ -201,18 +217,22 @@ extension ViewController: UICollectionViewDelegate { do { activityIndicatorView.startAnimating() - let driveInfo = try await self.client.send(AliyunpanScope.User.GetDriveInfo()) + let driveInfo = try await client + .authorize() + .send(AliyunpanScope.User.GetDriveInfo()) let driveId = driveInfo.default_drive_id - let response = try await self.client.send( - AliyunpanScope.File.CreateFile( - .init( - drive_id: driveId, - parent_file_id: "root", - name: "TestFolder", - type: .folder, - check_name_mode: .auto_rename))) + let response = try await client + .authorize() + .send( + AliyunpanScope.File.CreateFile( + .init( + drive_id: driveId, + parent_file_id: "root", + name: "TestFolder", + type: .folder, + check_name_mode: .auto_rename))) print(response) diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json new file mode 100644 index 0000000..950af4d --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.solidimagestacklayer" + }, + { + "filename" : "Middle.solidimagestacklayer" + }, + { + "filename" : "Back.solidimagestacklayer" + } + ] +} diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Demo/Demo/Demo-visionOS/Assets.xcassets/Contents.json b/Demo/Demo/Demo-visionOS/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Demo-visionOS/ContentView.swift b/Demo/Demo/Demo-visionOS/ContentView.swift new file mode 100644 index 0000000..e387834 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/ContentView.swift @@ -0,0 +1,82 @@ +// +// ContentView.swift +// Demo-visionOS +// +// Created by zhaixian on 2024/2/19. +// + +import SwiftUI +import RealityKit +import RealityKitContent +import AliyunpanSDK + +struct AuthorizeView: View { + @State var image = UIImage() + @State var status: AliyunpanAuthorizeQRCodeStatus? + @State var userInfo: AliyunpanScope.User.GetUsersInfo.Response? + + var isAuthorizing: Bool { + status != nil && status != .scanSuccess + } + + var isAuthorized: Bool { + userInfo != nil + } + + var showAuthorizeButton: Bool { + guard !isAuthorized else { + return false + } + return !isAuthorizing + } + + var body: some View { + Image(uiImage: image) + .padding(.bottom, 50) + + if showAuthorizeButton { + Button("Authorize") { + Task { + let userInfo = try await client.authorize( + credentials: .qrCode(self)) + .send(AliyunpanScope.User.GetUsersInfo()) + self.userInfo = userInfo + } + } + .font(.extraLargeTitle) + } else { + Text(userInfo?.name ?? "") + .font(.extraLargeTitle) + + Text(userInfo?.id ?? "") + .font(.largeTitle) + } + } +} + +extension AuthorizeView: AliyunpanQRCodeContainer { + func showAliyunpanAuthorizeQRCode(with url: URL) { + Task { + let (data, _) = try await URLSession.shared.data(from: url) + if let image = UIImage(data: data) { + self.image = image + } + } + } + + func authorizeQRCodeStatusUpdated(_ status: AliyunpanSDK.AliyunpanAuthorizeQRCodeStatus) { + self.status = status + } +} + +struct ContentView: View { + @State var authorizeView = AuthorizeView() + + var body: some View { + authorizeView + } +} + +#Preview(windowStyle: .automatic) { + ContentView() +} diff --git a/Demo/Demo/Demo-visionOS/Demo_visionOSApp.swift b/Demo/Demo/Demo-visionOS/Demo_visionOSApp.swift new file mode 100644 index 0000000..0c1cd36 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Demo_visionOSApp.swift @@ -0,0 +1,17 @@ +// +// Demo_visionOSApp.swift +// Demo-visionOS +// +// Created by zhaixian on 2024/2/19. +// + +import SwiftUI + +@main +struct Demo_visionOSApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/Demo/Demo/Demo-visionOS/Info.plist b/Demo/Demo/Demo-visionOS/Info.plist new file mode 100644 index 0000000..20f75e2 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Info.plist @@ -0,0 +1,15 @@ + + + + + UIApplicationSceneManifest + + UIApplicationPreferredDefaultSceneSessionRole + UIWindowSceneSessionRoleApplication + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + + + diff --git a/Demo/Demo/Demo-visionOS/Preview Content/Preview Assets.xcassets/Contents.json b/Demo/Demo/Demo-visionOS/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Demo/Demo/Demo-visionOS/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Demo/Podfile.lock b/Demo/Podfile.lock index 4cccebb..26921c1 100644 --- a/Demo/Podfile.lock +++ b/Demo/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - AliyunpanSDK (0.1.15) + - AliyunpanSDK (0.1.18) DEPENDENCIES: - AliyunpanSDK (from `../`) @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - AliyunpanSDK: 2f9e96863eaa3ff21b28b87d30d85bd627f718d0 + AliyunpanSDK: 59f71bc271322edb3eb39c6260a7a4ef616410c7 -PODFILE CHECKSUM: e82420c5d47daad41bcef90410d3046b609d0c2a +PODFILE CHECKSUM: 40334940ba0e4f081833162ea871b81051e79c17 COCOAPODS: 1.14.3 diff --git a/Demo/podfile b/Demo/podfile index 9cbd481..55ee058 100644 --- a/Demo/podfile +++ b/Demo/podfile @@ -12,3 +12,8 @@ target 'Demo-TVOS' do use_frameworks! pod 'AliyunpanSDK', :path => "../" end + +target 'Demo-visionOS' do + use_frameworks! + pod 'AliyunpanSDK', :path => "../" +end diff --git a/Package.swift b/Package.swift index 2ffabe8..0e8dbd9 100644 --- a/Package.swift +++ b/Package.swift @@ -1,22 +1,29 @@ // swift-tools-version: 5.7 -// The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "AliyunpanSDK", - platforms: [.iOS(.v13), .macOS(.v10_15), .tvOS(.v13)], + platforms: [ + .iOS(.v13), + .macOS(.v10_15), + .tvOS(.v13) + ], products: [ .library( name: "AliyunpanSDK", targets: [ - "AliyunpanSDK"]) + "AliyunpanSDK" + ] + ) ], targets: [ .target( - name: "AliyunpanSDK"), + name: "AliyunpanSDK" + ), .testTarget( name: "AliyunpanSDKTests", - dependencies: ["AliyunpanSDK"]) + dependencies: ["AliyunpanSDK"] + ) ] ) diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift new file mode 100644 index 0000000..8d4cde7 --- /dev/null +++ b/Package@swift-5.9.swift @@ -0,0 +1,30 @@ +// swift-tools-version: 5.9 + +import PackageDescription + +let package = Package( + name: "AliyunpanSDK", + platforms: [ + .iOS(.v13), + .macOS(.v10_15), + .tvOS(.v13), + .visionOS(.v1) + ], + products: [ + .library( + name: "AliyunpanSDK", + targets: [ + "AliyunpanSDK" + ] + ) + ], + targets: [ + .target( + name: "AliyunpanSDK" + ), + .testTarget( + name: "AliyunpanSDKTests", + dependencies: ["AliyunpanSDK"] + ) + ] +) diff --git a/README.md b/README.md index fa4f11c..a2e5320 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,17 @@ ## 快速开始 ### 1. 创建 Client +```swift +let client: AliyunpanClient = AliyunpanClient( + .init( + appId: "YOUR_APP_ID", + scope: "YOUR_SCOPE", // e.g. user:base,file:all:read + ) +) +``` -你可以使用 SDK 提供的任意授权方式创建 Client +### 2. 授权 +你可以使用 SDK 提供的多种授权方式授权 #### [Credentials](https://alibaba.github.io/aliyunpan-ios-sdk/Enums/AliyunpanCredentials.html) | 授权方式 | 描述 | **不需要** Server | **不需要**阿里云盘客户端 | @@ -38,31 +47,32 @@ | token | 注入 token 授权 | ✅ | ✅ | ```swift -let client: AliyunpanClient = AliyunpanClient( - .init( - appId: "YOUR_APP_ID", - scope: "YOUR_SCOPE", // e.g. user:base,file:all:read - credentials: YOUR_CREDENTIALS)) -``` +client.authorize(credentials: credentials) +``` -### 2. 发送命令 +### 3. 发送命令 使用 SDK,你可以轻松使用所有已提供的 OpenAPI 和它们的请求体、返回体模型 ```swift // Concurrency -try await client.send( - AliyunpanScope.User.GetUsersInfo()) // -> GetUsersInfo.Response - -try await client.send( - AliyunpanScope.File.GetFileList( - .init(drive_id: driveId, parent_file_id: "root")))) // -> GetFileList.Response +try await client + .authorize() // 默认 pkce + .send(AliyunpanScope.User.GetUsersInfo()) // -> GetUsersInfo.Response + +try await client + .authorize() + .send( + AliyunpanScope.File.GetFileList( + .init(drive_id: driveId, parent_file_id: "root")))) // -> GetFileList.Response // Closure -client.send( - AliyunpanScope.User.GetUsersInfo()) { result in - /// do something -} +client + .authorize() + .send( + AliyunpanScope.User.GetUsersInfo()) { result in + /// do something + } ``` ## 高级功能 @@ -120,6 +130,9 @@ end [👉 文档](https://alibaba.github.io/aliyunpan-ios-sdk/) +## TODO +- Alamofire、URLSession 拓展 + ## License This project is licensed under the [MIT License](LICENSE). diff --git a/Sources/AliyunpanSDK/AliyunpanClient.swift b/Sources/AliyunpanSDK/AliyunpanClient.swift index a69003e..d8a9b99 100644 --- a/Sources/AliyunpanSDK/AliyunpanClient.swift +++ b/Sources/AliyunpanSDK/AliyunpanClient.swift @@ -12,8 +12,6 @@ public struct AliyunpanClientConfig { public let appId: String /// 申请权限 public let scope: String - /// 鉴权方式 - public let credentials: AliyunpanCredentials /// 业务方自定义 id,可实现账号互绑 public var identifier: String? @@ -21,12 +19,10 @@ public struct AliyunpanClientConfig { /// - appId: 应用 ID /// - scope: 申请权限 /// - identifier: 业务方自定义 id - /// - credentials: 鉴权方式 - public init(appId: String, scope: String, identifier: String? = nil, credentials: AliyunpanCredentials) { + public init(appId: String, scope: String, identifier: String? = nil) { self.appId = appId self.scope = scope self.identifier = identifier - self.credentials = credentials } } @@ -66,20 +62,27 @@ public class AliyunpanClient { } } + public convenience init(appId: String, scope: String, identifier: String? = nil) { + self.init(.init(appId: appId, scope: scope, identifier: identifier)) + } + /// 强制清除 token 持久化 @MainActor public func cleanToken() { token = nil } /// 授权 - /// 如本地持久化有效会取持久化,否则会开始授权 - /// send 方法中会自动调用,通常无需主动调用该方法 + /// 如本地持久化未过期会取持久化,否则会开始授权 + /// - Parameter credentials: 授权方式 + /// - Returns: token @discardableResult - public func authorize() async throws -> AliyunpanToken { + public func authorize( + credentials: AliyunpanCredentials = .pkce + ) async throws -> AliyunpanToken { if let token = await token, !token.isExpired { return token } - let token = try await config.credentials.implement.authorize( + let token = try await credentials.implement.authorize( appId: config.appId, scope: config.scope ) @@ -88,7 +91,9 @@ public class AliyunpanClient { } return token } - +} + +extension AliyunpanToken { /// 发送请求 /// /// - throws: @@ -97,24 +102,10 @@ public class AliyunpanClient { /// `AliyunpanServerError`: 服务端错误 /// `AliyunpanNetworkSystemError`: 网络系统错误 public func send(_ command: T) async throws -> T.Response where T.Response: Decodable { - let accessToken = try await authorize().access_token - do { - let result = try await HTTPRequest(command: command) - .headers([.authorization(bearerToken: accessToken)]) - .response() - return result - } catch { - /// 授权过期重试 - if let error = error as? AliyunpanError.ServerError, - error.isAccessTokenInvalidOrExpired { - await MainActor.run { [weak self] in - self?.token = nil - } - return try await send(command) - } else { - throw error - } - } + let result = try await HTTPRequest(command: command) + .headers([.authorization(bearerToken: access_token)]) + .response() + return result } /// 发送请求 diff --git a/Sources/AliyunpanSDK/AliyunpanScope/Vip/GetVipFeatureList.swift b/Sources/AliyunpanSDK/AliyunpanScope/Vip/GetVipFeatureList.swift index 14f8292..1bf69ed 100644 --- a/Sources/AliyunpanSDK/AliyunpanScope/Vip/GetVipFeatureList.swift +++ b/Sources/AliyunpanSDK/AliyunpanScope/Vip/GetVipFeatureList.swift @@ -30,7 +30,7 @@ extension AliyunpanVIPScope { /// 允许试用的时间,单位分钟。 public let trialDuration: Int /// 开始试用的时间戳 - public let trialStartTime: TimeInterval + public let trialStartTime: TimeInterval? } /// 付费功能数组 diff --git a/Sources/AliyunpanSDK/HTTPRequest/Download/AliyunpanDownloader.swift b/Sources/AliyunpanSDK/HTTPRequest/Download/AliyunpanDownloader.swift index fd9ce9e..3a219f0 100644 --- a/Sources/AliyunpanSDK/HTTPRequest/Download/AliyunpanDownloader.swift +++ b/Sources/AliyunpanSDK/HTTPRequest/Download/AliyunpanDownloader.swift @@ -141,9 +141,11 @@ extension AliyunpanDownloader: AliyunpanDownloadTaskDelegate { guard let client else { throw AliyunpanError.DownloadError.invalidClient } - return try await client.send( - AliyunpanScope.File.GetFileDownloadUrl( - .init(drive_id: driveId, file_id: fileId))) + return try await client + .authorize() + .send( + AliyunpanScope.File.GetFileDownloadUrl( + .init(drive_id: driveId, file_id: fileId))) } func getOperationQueue() -> OperationQueue { diff --git a/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift b/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift index 8fda086..e005b77 100644 --- a/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift +++ b/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift @@ -10,9 +10,9 @@ import XCTest class AliyunpanClientTests: XCTestCase { @MainActor func testToken() { - let client1 = AliyunpanClient(.init(appId: "app", scope: "scope", identifier: "user1", credentials: .pkce)) - let client2 = AliyunpanClient(.init(appId: "app", scope: "scope", identifier: "user2", credentials: .pkce)) - let client3 = AliyunpanClient(.init(appId: "app", scope: "scope", credentials: .pkce)) + let client1 = AliyunpanClient(.init(appId: "app", scope: "scope", identifier: "user1")) + let client2 = AliyunpanClient(.init(appId: "app", scope: "scope", identifier: "user2")) + let client3 = AliyunpanClient(appId: "app", scope: "scope") let now = Date() let token = AliyunpanToken(