├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .gitmodules
├── .jazzy.json
├── .swift-version
├── .swiftformat
├── .swiftlint.yml
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDETemplateMacros.plist
├── Format
├── generate_docs.sh
└── jazzy.json
├── Images
├── InfoPlistExample.png
├── OAuthFlowApproval.png
└── OAuthFlowInit.png
├── LICENSE
├── Package.swift
├── README.md
├── Source
├── SwiftyDropbox
│ ├── Platform
│ │ ├── SwiftyDropbox_iOS
│ │ │ ├── Info.plist
│ │ │ ├── LoadingViewController.swift
│ │ │ ├── OAuthMobile.swift
│ │ │ └── UtilitiesMobile.swift
│ │ └── SwiftyDropbox_macOS
│ │ │ ├── Info.plist
│ │ │ └── OAuthDesktop.swift
│ ├── PrivacyInfo.xcprivacy
│ └── Shared
│ │ ├── Generated
│ │ ├── Account.swift
│ │ ├── AccountRoutes.swift
│ │ ├── AppAuthReconnectionHelpers.swift
│ │ ├── Async.swift
│ │ ├── Auth.swift
│ │ ├── AuthAppAuthRoutes.swift
│ │ ├── AuthRoutes.swift
│ │ ├── Base.swift
│ │ ├── BaseApp.swift
│ │ ├── BaseTeam.swift
│ │ ├── Check.swift
│ │ ├── CheckAppAuthRoutes.swift
│ │ ├── CheckRoutes.swift
│ │ ├── Common.swift
│ │ ├── Contacts.swift
│ │ ├── ContactsRoutes.swift
│ │ ├── DropboxAppBaseRequestBox.swift
│ │ ├── DropboxBaseRequestBox.swift
│ │ ├── FileProperties.swift
│ │ ├── FilePropertiesRoutes.swift
│ │ ├── FileRequests.swift
│ │ ├── FileRequestsRoutes.swift
│ │ ├── Files.swift
│ │ ├── FilesAppAuthRoutes.swift
│ │ ├── FilesRoutes.swift
│ │ ├── Openid.swift
│ │ ├── OpenidRoutes.swift
│ │ ├── Paper.swift
│ │ ├── PaperRoutes.swift
│ │ ├── ReconnectionHelpers.swift
│ │ ├── SecondaryEmails.swift
│ │ ├── SeenState.swift
│ │ ├── Sharing.swift
│ │ ├── SharingAppAuthRoutes.swift
│ │ ├── SharingRoutes.swift
│ │ ├── StoneBase.swift
│ │ ├── StoneSerializers.swift
│ │ ├── StoneValidators.swift
│ │ ├── Team.swift
│ │ ├── TeamCommon.swift
│ │ ├── TeamLog.swift
│ │ ├── TeamLogRoutes.swift
│ │ ├── TeamPolicies.swift
│ │ ├── TeamRoutes.swift
│ │ ├── Users.swift
│ │ ├── UsersCommon.swift
│ │ └── UsersRoutes.swift
│ │ └── Handwritten
│ │ ├── BackgroundClientSetupInfo.swift
│ │ ├── CertificatePinning.swift
│ │ ├── Custom
│ │ ├── ChunkInputStream.swift
│ │ ├── Custom.swift
│ │ ├── CustomRoutes.swift
│ │ └── CustomTasks.swift
│ │ ├── DropboxAppClient.swift
│ │ ├── DropboxClient.swift
│ │ ├── DropboxClientsManager.swift
│ │ ├── DropboxTeamClient.swift
│ │ ├── DropboxTransportClient.swift
│ │ ├── DropboxTransportClientInterface.swift
│ │ ├── Errors.swift
│ │ ├── FilesAcccess.swift
│ │ ├── GlobalErrorResponseHandler.swift
│ │ ├── MockApiRequest.swift
│ │ ├── MockDropboxTransportClient.swift
│ │ ├── NetworkSession
│ │ ├── Mocks
│ │ │ ├── MockNetworkDataTask.swift
│ │ │ └── MockNetworkSession.swift
│ │ ├── NetworkSession.swift
│ │ ├── NetworkSessionConfiguration.swift
│ │ ├── NetworkSessionManager.swift
│ │ └── NetworkTask.swift
│ │ ├── NoopRequest.swift
│ │ ├── OAuth
│ │ ├── AccessTokenProvider.swift
│ │ ├── AuthSession.swift
│ │ ├── OAuth.swift
│ │ ├── OAuthConstants.swift
│ │ ├── OAuthImpl.swift
│ │ ├── OAuthTokenRequest.swift
│ │ ├── OAuthUtils.swift
│ │ ├── Reachability.swift
│ │ └── SecureStorageAccess.swift
│ │ ├── ReconnectionHelpers+Handwritten.swift
│ │ ├── Request+Async.swift
│ │ ├── Request+TokenRefresh.swift
│ │ ├── Request.swift
│ │ ├── RequestMap.swift
│ │ ├── SDKConstants.swift
│ │ └── Utilities.swift
├── SwiftyDropboxObjC
│ ├── Platform
│ │ ├── SwiftyDropbox_iOS
│ │ │ ├── DBXOAuthMobile.swift
│ │ │ └── Info.plist
│ │ └── SwiftyDropbox_macOS
│ │ │ ├── DBXOAuthDesktop.swift
│ │ │ └── Info.plist
│ ├── PrivacyInfo.xcprivacy
│ └── Shared
│ │ ├── Generated
│ │ ├── DBXAccount.swift
│ │ ├── DBXAccountRoutes.swift
│ │ ├── DBXAsync.swift
│ │ ├── DBXAuth.swift
│ │ ├── DBXAuthAppAuthRoutes.swift
│ │ ├── DBXAuthRoutes.swift
│ │ ├── DBXBase.swift
│ │ ├── DBXBaseApp.swift
│ │ ├── DBXBaseTeam.swift
│ │ ├── DBXCheck.swift
│ │ ├── DBXCheckAppAuthRoutes.swift
│ │ ├── DBXCheckRoutes.swift
│ │ ├── DBXCommon.swift
│ │ ├── DBXContacts.swift
│ │ ├── DBXContactsRoutes.swift
│ │ ├── DBXDropboxAppBaseRequestBox.swift
│ │ ├── DBXDropboxBaseRequestBox.swift
│ │ ├── DBXFileProperties.swift
│ │ ├── DBXFilePropertiesRoutes.swift
│ │ ├── DBXFileRequests.swift
│ │ ├── DBXFileRequestsRoutes.swift
│ │ ├── DBXFiles.swift
│ │ ├── DBXFilesAppAuthRoutes.swift
│ │ ├── DBXFilesRoutes.swift
│ │ ├── DBXOpenid.swift
│ │ ├── DBXOpenidRoutes.swift
│ │ ├── DBXPaper.swift
│ │ ├── DBXPaperRoutes.swift
│ │ ├── DBXSecondaryEmails.swift
│ │ ├── DBXSeenState.swift
│ │ ├── DBXSharing.swift
│ │ ├── DBXSharingAppAuthRoutes.swift
│ │ ├── DBXSharingRoutes.swift
│ │ ├── DBXTeam.swift
│ │ ├── DBXTeamCommon.swift
│ │ ├── DBXTeamLog.swift
│ │ ├── DBXTeamLogRoutes.swift
│ │ ├── DBXTeamPolicies.swift
│ │ ├── DBXTeamRoutes.swift
│ │ ├── DBXUsers.swift
│ │ ├── DBXUsersCommon.swift
│ │ └── DBXUsersRoutes.swift
│ │ └── Handwritten
│ │ ├── DBXCallError.swift
│ │ ├── DBXCertificatePinning.swift
│ │ ├── DBXDropboxAppClient.swift
│ │ ├── DBXDropboxClient.swift
│ │ ├── DBXDropboxClientsManager.swift
│ │ ├── DBXDropboxTeamClient.swift
│ │ ├── DBXDropboxTransportClient.swift
│ │ ├── DBXReconnectionHelpers.swift
│ │ ├── DBXRequest.swift
│ │ ├── NetworkSession
│ │ └── DBXNetworkSessionConfiguration.swift
│ │ └── OAuth
│ │ ├── DBXAccessTokenProvider.swift
│ │ ├── DBXAuthSession.swift
│ │ ├── DBXOAuth.swift
│ │ ├── DBXOAuthImpl.swift
│ │ └── DBXSecureStorageAccess.swift
└── SwiftyDropboxUnitTests
│ ├── GlobalErrorResponseHandlerTests.swift
│ ├── OAuthImplTests.swift
│ ├── ReconnectionHelperPersistedRequestInfoTests.swift
│ ├── ReconnectionHelperRouteNameTests.swift
│ ├── Request+Async.test.swift
│ ├── TestAsciiEncoding.swift
│ ├── TestDropboxTransportClient.swift
│ ├── TestMockingUtilities.swift
│ ├── TestNetworkSessionManager+Background.swift
│ ├── TestNetworkSessionManager.swift
│ ├── TestOAuthTokenRequest.swift
│ ├── TestRequest.swift
│ ├── TestRequestMap.swift
│ ├── TestRequestWithTokenRefresh.swift
│ └── TestSecureStorageAccess.swift
├── SwiftyDropbox.podspec
├── SwiftyDropboxObjc.podspec
├── TestSwiftyDropbox
├── .swiftpm
│ └── xcode
│ │ └── package.xcworkspace
│ │ └── contents.xcworkspacedata
├── IntegrationTests
│ ├── BackgroundSessionTestClasses.swift
│ ├── ObjC
│ │ ├── ObjCTestClasses.h
│ │ ├── ObjCTestClasses.m
│ │ └── ObjCTestData.swift
│ ├── TestAppType.swift
│ ├── TestClasses.swift
│ └── TestData.swift
├── Package.swift
├── Podfile
├── Podfile.lock
├── TestSwiftyDropbox.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── TestSwiftyDropbox_ActionExtension.xcscheme
│ │ ├── TestSwiftyDropbox_iOS.xcscheme
│ │ └── TestSwiftyDropbox_macOS.xcscheme
├── TestSwiftyDropbox.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── TestSwiftyDropbox_ActionExtension
│ ├── ActionRequestHandler.swift
│ ├── Info.plist
│ └── TestSwiftyDropbox_ActionExtension.entitlements
├── TestSwiftyDropbox_SwiftUI
│ ├── Shared
│ │ └── Assets.xcassets
│ │ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ │ └── Contents.json
│ ├── iOS
│ │ ├── AppDelegate.swift
│ │ ├── ContentView.swift
│ │ ├── Info.plist
│ │ └── TestSwiftyDropboxApp.swift
│ └── macOS
│ │ ├── AppDelegate.swift
│ │ ├── ContentView.swift
│ │ ├── Info.plist
│ │ ├── TestSwiftyDropboxApp.swift
│ │ └── macOS.entitlements
├── TestSwiftyDropbox_iOS
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── DebugBackgroundSessionView.swift
│ ├── DebugBackgroundSessionViewModel.swift
│ ├── FileBrowserView.swift
│ ├── FileTextView.swift
│ ├── Info.plist
│ ├── Main.storyboard
│ ├── TestSwiftyDropbox.entitlements
│ ├── TestUtilities.swift
│ └── ViewController.swift
├── TestSwiftyDropbox_iOSTests
│ ├── CustomRoutesTests.swift
│ ├── FilesRoutesTests.swift
│ ├── Info.plist
│ ├── ObjCFilesRoutesTests.h
│ ├── ObjCFilesRoutesTests.m
│ ├── ObjCTeamRoutesTests.h
│ ├── ObjCTeamRoutesTests.m
│ ├── SwiftyDropboxTestExtensions.swift
│ └── TeamRoutesTests.swift
├── TestSwiftyDropbox_macOS
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Info.plist
│ └── ViewController.swift
├── TestSwiftyDropbox_macOSTests
│ └── Info.plist
└── TestUtils
│ └── TestTokenAuthGenerator.swift
├── generate_base_client.py
├── update_repo_check.sh
└── update_version.sh
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [pull_request, workflow_dispatch]
3 |
4 | jobs:
5 | test:
6 | name: Run Unit Tests
7 | runs-on: macos-13
8 | timeout-minutes: 45
9 |
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v2
13 | - name: Pod Install
14 | run: |
15 | cd TestSwiftyDropbox
16 | pod install --repo-update
17 | - name: Test iOS
18 | env:
19 | FULL_DROPBOX_API_APP_KEY: ${{ secrets.FULL_DROPBOX_API_APP_KEY }}
20 | FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN: ${{ secrets.FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN }}
21 | FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN: ${{ secrets.FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN }}
22 | TEAM_MEMBER_EMAIL: ${{ secrets.TEAM_MEMBER_EMAIL }}
23 | EMAIL_TO_ADD_AS_TEAM_MEMBER: ${{ secrets.EMAIL_TO_ADD_AS_TEAM_MEMBER }}
24 | ACCOUNT_ID: ${{ secrets.ACCOUNT_ID }}
25 | ACCOUNT_ID_2: ${{ secrets.ACCOUNT_ID_2 }}
26 | ACCOUNT_ID_3: ${{ secrets.ACCOUNT_ID_3 }}
27 | platform: ${{ 'iOS Simulator' }}
28 | device: ${{ 'iPhone 14' }}
29 | run: |
30 | xcodebuild -workspace TestSwiftyDropbox/TestSwiftyDropbox.xcworkspace/ -scheme TestSwiftyDropbox_iOS -sdk iphonesimulator \
31 | -destination "platform=$platform,name=$device" \
32 | FULL_DROPBOX_API_APP_KEY=$FULL_DROPBOX_API_APP_KEY \
33 | FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN=$FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN \
34 | FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN=$FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN \
35 | TEAM_MEMBER_EMAIL=$TEAM_MEMBER_EMAIL \
36 | EMAIL_TO_ADD_AS_TEAM_MEMBER=$EMAIL_TO_ADD_AS_TEAM_MEMBER \
37 | ACCOUNT_ID=$ACCOUNT_ID \
38 | ACCOUNT_ID_2=$ACCOUNT_ID_2 \
39 | ACCOUNT_ID_3=$ACCOUNT_ID_3 \
40 | test
41 |
42 | - name: Test macOS
43 | env:
44 | FULL_DROPBOX_API_APP_KEY: ${{ secrets.FULL_DROPBOX_API_APP_KEY }}
45 | FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN: ${{ secrets.FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN }}
46 | FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN: ${{ secrets.FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN }}
47 | TEAM_MEMBER_EMAIL: ${{ secrets.TEAM_MEMBER_EMAIL }}
48 | EMAIL_TO_ADD_AS_TEAM_MEMBER: ${{ secrets.EMAIL_TO_ADD_AS_TEAM_MEMBER }}
49 | ACCOUNT_ID: ${{ secrets.ACCOUNT_ID }}
50 | ACCOUNT_ID_2: ${{ secrets.ACCOUNT_ID_2 }}
51 | ACCOUNT_ID_3: ${{ secrets.ACCOUNT_ID_3 }}
52 | platform: ${{ 'macOS' }}
53 | run: |
54 | xcodebuild -workspace TestSwiftyDropbox/TestSwiftyDropbox.xcworkspace/ -scheme TestSwiftyDropbox_macOS \
55 | -destination "platform=$platform,arch=x86_64" \
56 | FULL_DROPBOX_API_APP_KEY=$FULL_DROPBOX_API_APP_KEY \
57 | FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN=$FULL_DROPBOX_TESTER_TEAM_REFRESH_TOKEN \
58 | FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN=$FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN \
59 | TEAM_MEMBER_EMAIL=$TEAM_MEMBER_EMAIL \
60 | EMAIL_TO_ADD_AS_TEAM_MEMBER=$EMAIL_TO_ADD_AS_TEAM_MEMBER \
61 | ACCOUNT_ID=$ACCOUNT_ID \
62 | ACCOUNT_ID_2=$ACCOUNT_ID_2 \
63 | ACCOUNT_ID_3=$ACCOUNT_ID_3 \
64 | test
65 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## macOS
2 | .DS_Store
3 | .arcconfig
4 |
5 | ## Xcode
6 | xcuserdata/
7 | build/
8 |
9 | ## CocoaPods
10 | Pods/
11 |
12 | ## Swift Package Manager
13 | Packages/
14 | .build/
15 | .swiftpm/xcode/xcuserdata
16 | .swiftpm/xcode/package.xcworkspace/xcuserdata
17 |
18 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "stone"]
2 | path = stone
3 | url = https://github.com/dropbox/stone.git
4 | [submodule "spec"]
5 | path = spec
6 | url = https://github.com/dropbox/dropbox-api-spec.git
7 |
--------------------------------------------------------------------------------
/.jazzy.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Dropbox, Inc.",
3 | "author_url": "https://dropbox.com/developers",
4 | "skip_undocumented": true,
5 | "hide_documentation_coverage": true,
6 | "exclude": [
7 | "Source/StoneSerializers.swift",
8 | "Source/StoneValidators.swift",
9 | "Source/DropboxTransportClient.swift"
10 | ],
11 | "custom_categories": [
12 | {
13 | "name": "Routes",
14 | "children": [
15 | "AccountRoutes",
16 | "AuthRoutes",
17 | "CheckRoutes",
18 | "ContactsRoutes",
19 | "FilePropertiesRoutes",
20 | "FileRequestsRoutes",
21 | "FilesRoutes",
22 | "OpenidRoutes",
23 | "PaperRoutes",
24 | "SharingRoutes",
25 | "TeamRoutes",
26 | "TeamLogRoutes",
27 | "UsersRoutes"
28 | ]
29 | },
30 | {
31 | "name": "Data Types",
32 | "children": [
33 | "Account",
34 | "Async",
35 | "Auth",
36 | "Check",
37 | "Common",
38 | "Contacts",
39 | "FileProperties",
40 | "FileRequests",
41 | "Files",
42 | "Openid",
43 | "Paper",
44 | "SecondaryEmails",
45 | "SeenState",
46 | "Sharing",
47 | "Team",
48 | "TeamCommon",
49 | "TeamLog",
50 | "TeamPolicies",
51 | "Users",
52 | "UsersCommon"
53 | ]
54 | },
55 | {
56 | "name": "Authentication",
57 | "children": [
58 | "DropboxOAuthManager",
59 | "DropboxOAuthResult",
60 | "DropboxAccessToken",
61 | "OAuth2Error"
62 | ]
63 | },
64 | {
65 | "name": "Client Classes",
66 | "children": [
67 | "DropboxClient",
68 | "DropboxTeamClient",
69 | "DropboxClientsManager"
70 | ]
71 | }
72 | ]
73 | }
74 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.6
2 |
--------------------------------------------------------------------------------
/.swiftformat:
--------------------------------------------------------------------------------
1 | --exclude stone,spec
2 | --ifdef no-indent
3 | --maxwidth 160
4 | --trimwhitespace always
5 | --hexliteralcase lowercase
6 | --semicolons never
7 | --stripunusedargs closure-only
8 | --decimalgrouping 3
9 | --disable trailingClosures
10 | --wraparguments before-first
11 | --wrapcollections before-first
12 | --wrapparameters before-first
13 | --closingparen balanced
14 | --self init-only
15 | --disable andOperator
16 | --disable linebreakAtEndOfFile
17 | --disable hoistPatternLet
18 | --specifierorder public,open,override
19 | --disable extensionAccessControl
20 | --disable wrapMultilineStatementBraces
21 | --disable redundantType
22 | --disable enumNamespaces
23 | --disable redundantClosure
24 | --disable redundantVoidReturnType
25 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | disabled_rules: # rule identifiers to exclude from running
2 | # - colon
3 | # - comma
4 | # - control_statement
5 | opt_in_rules: # some rules are only opt-in
6 | - empty_count
7 | - missing_docs
8 | # Find all the available rules by running:
9 | # swiftlint rules
10 | included: # paths to include during linting. `--path` is ignored if present.
11 | - Source
12 | excluded: # paths to ignore during linting. Takes precedence over `included`.
13 | - Carthage
14 | - Pods
15 | - Source/ExcludedFolder
16 | - Source/ExcludedFile.swift
17 |
18 | # configurable rules can be customized from this configuration file
19 | # binary rules can set their severity level
20 | force_cast: warning # implicitly
21 | force_try:
22 | severity: warning # explicitly
23 | # rules that have both warning and error levels, can set just the warning level
24 | # implicitly
25 | line_length:
26 | - 50 # warning
27 | - 70 # error
28 | # they can set both implicitly with an array
29 | type_body_length:
30 | - 300 # warning
31 | - 400 # error
32 | # or they can set both explicitly
33 | file_length:
34 | warning: 500
35 | error: 1200
36 | # naming rules can set warnings/errors for min_length and max_length
37 | # additionally they can set excluded names
38 | type_name:
39 | min_length: 4 # only warning
40 | max_length: # warning and error
41 | warning: 40
42 | error: 50
43 | excluded: iPhone # excluded via string
44 | variable_name:
45 | min_length: # only min_length
46 | error: 4 # only error
47 | excluded: # excluded via string array
48 | - id
49 | - URL
50 | - GlobalAPIKey
51 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit)
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDETemplateMacros.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | FILEHEADER
6 | /
7 | /// Copyright (c) ___YEAR___ Dropbox, Inc. All rights reserved.
8 | ///
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Format/generate_docs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Script for generating jazzy docs
3 |
4 | if [ "$#" -ne 2 ]; then
5 | echo "Script requires two arguments: 1. path to docs repo checkout 2. path to updated SDK checkout."
6 | else
7 | sdk_version="$(git describe --abbrev=0 --tags)"
8 | docs_repo_location="$1"
9 | sdk_repo_location="$2"
10 |
11 | echo "Checking doc repo exists..."
12 |
13 | if [ -d $docs_repo_location ]; then
14 | if [ -d $sdk_repo_location ]; then
15 | docs_location="$docs_repo_location/api-docs/$sdk_version"
16 | if [ -d $docs_location ]; then
17 | rm -rf $docs_location
18 | fi
19 |
20 | mkdir $docs_location
21 |
22 | echo "Generating documents..."
23 | cd ..
24 | jazzy --readme $sdk_repo_location/README.md --config $sdk_repo_location/.jazzy.json --github_url https://github.com/dropbox/SwiftyDropbox --module-version $sdk_version --podspec SwiftyDropbox.podspec -o $docs_location
25 | cd -
26 |
27 | cd $docs_repo_location/api-docs
28 | rm -rf latest
29 | mkdir latest
30 | cp -R $sdk_version/* latest/
31 | cd -
32 |
33 | echo "Finished generating docs to: $docs_repo_location/api-docs."
34 | else
35 | echo "SDK directory does not exist"
36 | fi
37 | else
38 | echo "Docs directory does not exist"
39 | fi
40 | fi
41 |
--------------------------------------------------------------------------------
/Format/jazzy.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Dropbox, Inc.",
3 | "author_url": "https://dropbox.com/developers",
4 | "skip_undocumented": true,
5 | "hide_documentation_coverage": true,
6 | "exclude": [
7 | "Source/StoneSerializers.swift",
8 | "Source/StoneValidators.swift",
9 | "Source/DropboxTransportClient.swift"
10 | ],
11 | "custom_categories": [
12 | {
13 | "name": "Routes",
14 | "children": []
15 | },
16 | {
17 | "name": "Data Types",
18 | "children": []
19 | },
20 | {
21 | "name": "Authentication",
22 | "children": [
23 | "DropboxOAuthManager",
24 | "DropboxOAuthResult",
25 | "DropboxAccessToken",
26 | "OAuth2Error"
27 | ]
28 | },
29 | {
30 | "name": "Client Classes",
31 | "children": [
32 | "DropboxClient",
33 | "DropboxTeamClient",
34 | "DropboxClientsManager"
35 | ]
36 | }
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/Images/InfoPlistExample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dropbox/SwiftyDropbox/ce29a217890382615934425f0696b02839cbacbe/Images/InfoPlistExample.png
--------------------------------------------------------------------------------
/Images/OAuthFlowApproval.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dropbox/SwiftyDropbox/ce29a217890382615934425f0696b02839cbacbe/Images/OAuthFlowApproval.png
--------------------------------------------------------------------------------
/Images/OAuthFlowInit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dropbox/SwiftyDropbox/ce29a217890382615934425f0696b02839cbacbe/Images/OAuthFlowInit.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015-2021 Dropbox Inc., http://www.dropbox.com/
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.6
2 | ///
3 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
4 | ///
5 |
6 | import PackageDescription
7 |
8 | let package = Package(
9 | name: "SwiftyDropbox",
10 | platforms: [
11 | .macOS(.v10_13),
12 | .iOS(.v11),
13 | ],
14 | products: [
15 | .library(name: "SwiftyDropbox", targets: ["SwiftyDropbox"]),
16 | .library(name: "SwiftyDropboxObjC", targets: ["SwiftyDropboxObjC"]),
17 | ],
18 | targets: [
19 | .target(
20 | name: "SwiftyDropbox",
21 | path: "Source/SwiftyDropbox",
22 | resources: [.process("PrivacyInfo.xcprivacy")]
23 | ),
24 | .target(
25 | name: "SwiftyDropboxObjC",
26 | dependencies: ["SwiftyDropbox"],
27 | path: "Source/SwiftyDropboxObjC",
28 | resources: [.process("PrivacyInfo.xcprivacy")]
29 | ),
30 | .testTarget(
31 | name: "SwiftyDropboxUnitTests",
32 | dependencies: ["SwiftyDropbox"]
33 | ),
34 | ],
35 | swiftLanguageVersions: [.v5]
36 | )
37 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Platform/SwiftyDropbox_iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 7.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 10.2.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Platform/SwiftyDropbox_iOS/LoadingViewController.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2020 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | #if canImport(UIKit)
6 |
7 | import Foundation
8 | import UIKit
9 |
10 | /// A VC with a loading spinner at its view center.
11 | class LoadingViewController: UIViewController {
12 | private let loadingSpinner: UIActivityIndicatorView
13 |
14 | override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
15 | if #available(iOS 13.0, *) {
16 | loadingSpinner = UIActivityIndicatorView(style: .large)
17 | } else {
18 | self.loadingSpinner = UIActivityIndicatorView(style: .whiteLarge)
19 | }
20 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
21 | }
22 |
23 | @available(*, unavailable, message: "init(coder:) has not been implemented")
24 | required init?(coder: NSCoder) {
25 | fatalError("init(coder:) has not been implemented")
26 | }
27 |
28 | override func viewDidLoad() {
29 | view.backgroundColor = UIColor.black.withAlphaComponent(0.4)
30 | view.addSubview(loadingSpinner)
31 | loadingSpinner.translatesAutoresizingMaskIntoConstraints = false
32 | NSLayoutConstraint.activate([
33 | loadingSpinner.centerXAnchor.constraint(equalTo: view.centerXAnchor),
34 | loadingSpinner.centerYAnchor.constraint(equalTo: view.centerYAnchor),
35 | ])
36 | loadingSpinner.startAnimating()
37 | }
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Platform/SwiftyDropbox_iOS/UtilitiesMobile.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2022 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | #if os(iOS)
6 |
7 | import Foundation
8 | import UIKit
9 |
10 | @available(iOS 13.0, *)
11 | extension UIApplication {
12 | public func findKeyWindow() -> UIWindow? {
13 | connectedScenes
14 | .filter({ $0.activationState == .foregroundActive })
15 | .compactMap({ $0 as? UIWindowScene })
16 | .first?.windows
17 | .filter(\.isKeyWindow).first
18 | }
19 | }
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Platform/SwiftyDropbox_macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 7.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 10.2.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSHumanReadableCopyright
22 | Copyright © 2016 Dropbox. All rights reserved.
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/AccountRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the account namespace
10 | /// For Objective-C compatible routes see DBAccountRoutes
11 | public class AccountRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// Sets a user's profile photo.
18 | ///
19 | /// - scope: account_info.write
20 | ///
21 | /// - parameter photo: Image to set as the user's new profile photo.
22 | ///
23 | /// - returns: Through the response callback, the caller will receive a `Account.SetProfilePhotoResult` object on
24 | /// success or a `Account.SetProfilePhotoError` object on failure.
25 | @discardableResult public func setProfilePhoto(
26 | photo: Account
27 | .PhotoSourceArg
28 | ) -> RpcRequest {
29 | let route = Account.setProfilePhoto
30 | let serverArgs = Account.SetProfilePhotoArg(photo: photo)
31 | return client.request(route, serverArgs: serverArgs)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/AppAuthReconnectionHelpers.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | // The case string below must match those created by ReconnectionHelpers+Handwritten.swift using
8 | // the route name and namespace as formatted for the generated `Route` object in SwiftTypes.jinja
9 | // Format: "/" e.g., "files/upload_session/append_v2" for Files.uploadSessionAppendV2
10 | enum AppAuthReconnectionHelpers: ReconnectionHelpersShared {
11 | static func rebuildRequest(apiRequest: ApiRequest, client: DropboxTransportClientInternal) throws -> DropboxAppBaseRequestBox {
12 | let info = try persistedRequestInfo(from: apiRequest)
13 |
14 | switch info.namespaceRouteName {
15 | case "files/get_thumbnail_v2":
16 | return .files_getThumbnailV2(
17 | rebuildRequest(
18 | apiRequest: apiRequest,
19 | info: info,
20 | route: Files.getThumbnailV2,
21 | client: client
22 | )
23 | )
24 | default:
25 | throw ReconnectionErrorKind.missingReconnectionCase
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/AuthAppAuthRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the authAppAuth namespace
10 | /// For Objective-C compatible routes see DBAuthRoutes
11 | public class AuthAppAuthRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// Creates an OAuth 2.0 access token from the supplied OAuth 1.0 access token.
18 | ///
19 | /// - parameter oauth1Token: The supplied OAuth 1.0 access token.
20 | /// - parameter oauth1TokenSecret: The token secret associated with the supplied access token.
21 | ///
22 | /// - returns: Through the response callback, the caller will receive a `Auth.TokenFromOAuth1Result` object on
23 | /// success or a `Auth.TokenFromOAuth1Error` object on failure.
24 | @available(*, unavailable, message: "tokenFromOauth1 is deprecated.")
25 | @discardableResult public func tokenFromOauth1(
26 | oauth1Token: String,
27 | oauth1TokenSecret: String
28 | ) -> RpcRequest {
29 | let route = Auth.tokenFromOauth1
30 | let serverArgs = Auth.TokenFromOAuth1Arg(oauth1Token: oauth1Token, oauth1TokenSecret: oauth1TokenSecret)
31 | return client.request(route, serverArgs: serverArgs)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/AuthRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the auth namespace
10 | /// For Objective-C compatible routes see DBAuthRoutes
11 | public class AuthRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// Disables the access token used to authenticate the call. If there is a corresponding refresh token for the
18 | /// access token, this disables that refresh token, as well as any other access tokens for that refresh token.
19 | ///
20 | ///
21 | /// - returns: Through the response callback, the caller will receive a `Void` object on success or a `Void` object
22 | /// on failure.
23 | @discardableResult public func tokenRevoke() -> RpcRequest {
24 | let route = Auth.tokenRevoke
25 | return client.request(route)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/Base.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | public class DropboxBase: DropboxTransportClientOwning {
10 | public var client: DropboxTransportClient
11 |
12 | /// Routes within the account namespace. See AccountRoutes for details.
13 | public var account: AccountRoutes!
14 | /// Routes within the auth namespace. See AuthRoutes for details.
15 | public var auth: AuthRoutes!
16 | /// Routes within the check namespace. See CheckRoutes for details.
17 | public var check: CheckRoutes!
18 | /// Routes within the contacts namespace. See ContactsRoutes for details.
19 | public var contacts: ContactsRoutes!
20 | /// Routes within the fileProperties namespace. See FilePropertiesRoutes for details.
21 | public var fileProperties: FilePropertiesRoutes!
22 | /// Routes within the fileRequests namespace. See FileRequestsRoutes for details.
23 | public var fileRequests: FileRequestsRoutes!
24 | /// Routes within the files namespace. See FilesRoutes for details.
25 | public var files: FilesRoutes!
26 | /// Routes within the openid namespace. See OpenidRoutes for details.
27 | public var openid: OpenidRoutes!
28 | /// Routes within the paper namespace. See PaperRoutes for details.
29 | public var paper: PaperRoutes!
30 | /// Routes within the sharing namespace. See SharingRoutes for details.
31 | public var sharing: SharingRoutes!
32 | /// Routes within the teamLog namespace. See TeamLogRoutes for details.
33 | public var teamLog: TeamLogRoutes!
34 | /// Routes within the users namespace. See UsersRoutes for details.
35 | public var users: UsersRoutes!
36 |
37 | public required init(client: DropboxTransportClient) {
38 | self.client = client
39 |
40 | self.account = AccountRoutes(client: client)
41 | self.auth = AuthRoutes(client: client)
42 | self.check = CheckRoutes(client: client)
43 | self.contacts = ContactsRoutes(client: client)
44 | self.fileProperties = FilePropertiesRoutes(client: client)
45 | self.fileRequests = FileRequestsRoutes(client: client)
46 | self.files = FilesRoutes(client: client)
47 | self.openid = OpenidRoutes(client: client)
48 | self.paper = PaperRoutes(client: client)
49 | self.sharing = SharingRoutes(client: client)
50 | self.teamLog = TeamLogRoutes(client: client)
51 | self.users = UsersRoutes(client: client)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/BaseApp.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | public class DropboxAppBase: DropboxTransportClientOwning {
10 | public var client: DropboxTransportClient
11 |
12 | /// Routes within the auth namespace. See AuthAppAuthRoutes for details.
13 | public var auth: AuthAppAuthRoutes!
14 | /// Routes within the check namespace. See CheckAppAuthRoutes for details.
15 | public var check: CheckAppAuthRoutes!
16 | /// Routes within the files namespace. See FilesAppAuthRoutes for details.
17 | public var files: FilesAppAuthRoutes!
18 | /// Routes within the sharing namespace. See SharingAppAuthRoutes for details.
19 | public var sharing: SharingAppAuthRoutes!
20 |
21 | public required init(client: DropboxTransportClient) {
22 | self.client = client
23 |
24 | self.auth = AuthAppAuthRoutes(client: client)
25 | self.check = CheckAppAuthRoutes(client: client)
26 | self.files = FilesAppAuthRoutes(client: client)
27 | self.sharing = SharingAppAuthRoutes(client: client)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/BaseTeam.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | public class DropboxTeamBase: DropboxTransportClientOwning {
10 | public var client: DropboxTransportClient
11 |
12 | /// Routes within the team namespace. See TeamRoutes for details.
13 | public var team: TeamRoutes!
14 |
15 | public required init(client: DropboxTransportClient) {
16 | self.client = client
17 |
18 | self.team = TeamRoutes(client: client)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/CheckAppAuthRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the checkAppAuth namespace
10 | /// For Objective-C compatible routes see DBCheckRoutes
11 | public class CheckAppAuthRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// This endpoint performs App Authentication, validating the supplied app key and secret, and returns the supplied
18 | /// string, to allow you to test your code and connection to the Dropbox API. It has no other effect. If you
19 | /// receive an HTTP 200 response with the supplied query, it indicates at least part of the Dropbox API
20 | /// infrastructure is working and that the app key and secret valid.
21 | ///
22 | /// - parameter query: The string that you'd like to be echoed back to you.
23 | ///
24 | /// - returns: Through the response callback, the caller will receive a `Check.EchoResult` object on success or a
25 | /// `Void` object on failure.
26 | @discardableResult public func app(query: String = "") -> RpcRequest {
27 | let route = Check.app
28 | let serverArgs = Check.EchoArg(query: query)
29 | return client.request(route, serverArgs: serverArgs)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/CheckRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the check namespace
10 | /// For Objective-C compatible routes see DBCheckRoutes
11 | public class CheckRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// This endpoint performs User Authentication, validating the supplied access token, and returns the supplied
18 | /// string, to allow you to test your code and connection to the Dropbox API. It has no other effect. If you
19 | /// receive an HTTP 200 response with the supplied query, it indicates at least part of the Dropbox API
20 | /// infrastructure is working and that the access token is valid.
21 | ///
22 | /// - scope: account_info.read
23 | ///
24 | /// - parameter query: The string that you'd like to be echoed back to you.
25 | ///
26 | /// - returns: Through the response callback, the caller will receive a `Check.EchoResult` object on success or a
27 | /// `Void` object on failure.
28 | @discardableResult public func user(query: String = "") -> RpcRequest {
29 | let route = Check.user
30 | let serverArgs = Check.EchoArg(query: query)
31 | return client.request(route, serverArgs: serverArgs)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/ContactsRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the contacts namespace
10 | /// For Objective-C compatible routes see DBContactsRoutes
11 | public class ContactsRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// Removes all manually added contacts. You'll still keep contacts who are on your team or who you imported. New
18 | /// contacts will be added when you share.
19 | ///
20 | /// - scope: contacts.write
21 | ///
22 | ///
23 | /// - returns: Through the response callback, the caller will receive a `Void` object on success or a `Void` object
24 | /// on failure.
25 | @discardableResult public func deleteManualContacts() -> RpcRequest {
26 | let route = Contacts.deleteManualContacts
27 | return client.request(route)
28 | }
29 |
30 | /// Removes manually added contacts from the given list.
31 | ///
32 | /// - scope: contacts.write
33 | ///
34 | /// - parameter emailAddresses: List of manually added contacts to be deleted.
35 | ///
36 | /// - returns: Through the response callback, the caller will receive a `Void` object on success or a
37 | /// `Contacts.DeleteManualContactsError` object on failure.
38 | @discardableResult public func deleteManualContactsBatch(emailAddresses: [String])
39 | -> RpcRequest {
40 | let route = Contacts.deleteManualContactsBatch
41 | let serverArgs = Contacts.DeleteManualContactsArg(emailAddresses: emailAddresses)
42 | return client.request(route, serverArgs: serverArgs)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/DropboxAppBaseRequestBox.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Allows for heterogenous collections of typed requests
10 | public enum DropboxAppBaseRequestBox: CustomStringConvertible {
11 | case files_getThumbnailV2(DownloadRequestFile)
12 |
13 | public var description: String {
14 | switch self {
15 | case .files_getThumbnailV2:
16 | return "files/get_thumbnail_v2"
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/OpenidRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the openid namespace
10 | /// For Objective-C compatible routes see DBOpenidRoutes
11 | public class OpenidRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// This route is used for refreshing the info that is found in the id_token during the OIDC flow. This route
18 | /// doesn't require any arguments and will use the scopes approved for the given access token.
19 | ///
20 | /// - scope: openid
21 | ///
22 | ///
23 | /// - returns: Through the response callback, the caller will receive a `Openid.UserInfoResult` object on success or
24 | /// a `Openid.UserInfoError` object on failure.
25 | @discardableResult public func userinfo() -> RpcRequest {
26 | let route = Openid.userinfo
27 | let serverArgs = Openid.UserInfoArgs()
28 | return client.request(route, serverArgs: serverArgs)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/SecondaryEmails.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Datatypes and serializers for the secondary_emails namespace
10 | public class SecondaryEmails {
11 | /// The SecondaryEmail struct
12 | public class SecondaryEmail: CustomStringConvertible, JSONRepresentable {
13 | /// Secondary email address.
14 | public let email: String
15 | /// Whether or not the secondary email address is verified to be owned by a user.
16 | public let isVerified: Bool
17 | public init(email: String, isVerified: Bool) {
18 | stringValidator(maxLength: 255, pattern: "^['#&A-Za-z0-9._%+-]+@[A-Za-z0-9-][A-Za-z0-9.-]*\\.[A-Za-z]{2,15}$")(email)
19 | self.email = email
20 | self.isVerified = isVerified
21 | }
22 |
23 | func json() throws -> JSON {
24 | try SecondaryEmailSerializer().serialize(self)
25 | }
26 |
27 | public var description: String {
28 | do {
29 | return "\(SerializeUtil.prepareJSONForSerialization(try SecondaryEmailSerializer().serialize(self)))"
30 | } catch {
31 | return "Failed to generate description for SecondaryEmail: \(error)"
32 | }
33 | }
34 | }
35 |
36 | public class SecondaryEmailSerializer: JSONSerializer {
37 | public init() {}
38 | public func serialize(_ value: SecondaryEmail) throws -> JSON {
39 | let output = [
40 | "email": try Serialization._StringSerializer.serialize(value.email),
41 | "is_verified": try Serialization._BoolSerializer.serialize(value.isVerified),
42 | ]
43 | return .dictionary(output)
44 | }
45 |
46 | public func deserialize(_ json: JSON) throws -> SecondaryEmail {
47 | switch json {
48 | case .dictionary(let dict):
49 | let email = try Serialization._StringSerializer.deserialize(dict["email"] ?? .null)
50 | let isVerified = try Serialization._BoolSerializer.deserialize(dict["is_verified"] ?? .null)
51 | return SecondaryEmail(email: email, isVerified: isVerified)
52 | default:
53 | throw JSONSerializerError.deserializeError(type: SecondaryEmail.self, json: json)
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/SharingAppAuthRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the sharingAppAuth namespace
10 | /// For Objective-C compatible routes see DBSharingRoutes
11 | public class SharingAppAuthRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// Get the shared link's metadata.
18 | ///
19 | /// - scope: sharing.read
20 | ///
21 | /// - parameter url: URL of the shared link.
22 | /// - parameter path: If the shared link is to a folder, this parameter can be used to retrieve the metadata for a
23 | /// specific file or sub-folder in this folder. A relative path should be used.
24 | /// - parameter linkPassword: If the shared link has a password, this parameter can be used.
25 | ///
26 | /// - returns: Through the response callback, the caller will receive a `Sharing.SharedLinkMetadata` object on
27 | /// success or a `Sharing.SharedLinkError` object on failure.
28 | @discardableResult public func getSharedLinkMetadata(
29 | url: String,
30 | path: String? = nil,
31 | linkPassword: String? = nil
32 | ) -> RpcRequest {
33 | let route = Sharing.getSharedLinkMetadata
34 | let serverArgs = Sharing.GetSharedLinkMetadataArg(url: url, path: path, linkPassword: linkPassword)
35 | return client.request(route, serverArgs: serverArgs)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/StoneBase.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | // The objects in this file are used by generated code and should not need to be invoked manually.
8 |
9 | public enum RouteAuth: String {
10 | case app
11 | case user
12 | case team
13 | case noauth
14 | }
15 |
16 | public enum RouteHost: String {
17 | case api
18 | case content
19 | case notify
20 | }
21 |
22 | public enum RouteStyle: String {
23 | case rpc
24 | case upload
25 | case download
26 | }
27 |
28 | public struct RouteAttributes {
29 | let auth: [RouteAuth]
30 | let host: RouteHost
31 | let style: RouteStyle
32 | }
33 |
34 | public class Route {
35 | public let name: String
36 | public let version: Int32
37 | public let namespace: String
38 | public let deprecated: Bool
39 | public let argSerializer: ASerial
40 | public let responseSerializer: RSerial
41 | public let errorSerializer: ESerial
42 | public let attributes: RouteAttributes
43 |
44 | public init(
45 | name: String,
46 | version: Int32,
47 | namespace: String,
48 | deprecated: Bool,
49 | argSerializer: ASerial,
50 | responseSerializer: RSerial,
51 | errorSerializer: ESerial,
52 | attributes: RouteAttributes
53 | ) {
54 | self.name = name
55 | self.version = version
56 | self.namespace = namespace
57 | self.deprecated = deprecated
58 | self.argSerializer = argSerializer
59 | self.responseSerializer = responseSerializer
60 | self.errorSerializer = errorSerializer
61 | self.attributes = attributes
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/StoneValidators.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | // The objects in this file are used by generated code and should not need to be invoked manually.
8 |
9 | var _assertFunc: (Bool, String) -> Void = { cond, message in precondition(cond, message) }
10 |
11 | public func setAssertFunc(_ assertFunc: @escaping (Bool, String) -> Void) {
12 | _assertFunc = assertFunc
13 | }
14 |
15 | public func arrayValidator(minItems: Int? = nil, maxItems: Int? = nil, itemValidator: @escaping (T) -> Void) -> ([T]) -> Void {
16 | { (value: [T]) -> Void in
17 | if let minItems = minItems {
18 | _assertFunc(value.count >= minItems, "\(value) must have at least \(minItems) items")
19 | }
20 |
21 | if let maxItems = maxItems {
22 | _assertFunc(value.count <= maxItems, "\(value) must have at most \(maxItems) items")
23 | }
24 |
25 | for el in value {
26 | itemValidator(el)
27 | }
28 | }
29 | }
30 |
31 | public func stringValidator(minLength: Int? = nil, maxLength: Int? = nil, pattern: String? = nil) -> (String) -> Void {
32 | { (value: String) -> Void in
33 | let length = value.count
34 | if let minLength = minLength {
35 | _assertFunc(length >= minLength, "\"\(value)\" must be at least \(minLength) characters")
36 | }
37 | if let maxLength = maxLength {
38 | _assertFunc(length <= maxLength, "\"\(value)\" must be at most \(maxLength) characters")
39 | }
40 |
41 | if let pat = pattern {
42 | // patterns much match entire input sequence
43 | let re = try! NSRegularExpression(pattern: "\\A(?:\(pat))\\z", options: NSRegularExpression.Options())
44 | let matches = re.matches(in: value, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: length))
45 | _assertFunc(matches.count > 0, "\"\(value) must match pattern \"\(re.pattern)\"")
46 | }
47 | }
48 | }
49 |
50 | public func comparableValidator(minValue: T? = nil, maxValue: T? = nil) -> (T) -> Void {
51 | { (value: T) -> Void in
52 | if let minValue = minValue {
53 | _assertFunc(minValue <= value, "\(value) must be at least \(minValue)")
54 | }
55 |
56 | if let maxValue = maxValue {
57 | _assertFunc(maxValue >= value, "\(value) must be at most \(maxValue)")
58 | }
59 | }
60 | }
61 |
62 | public func nullableValidator(_ internalValidator: @escaping (T) -> Void) -> (T?) -> Void {
63 | { (value: T?) -> Void in
64 | if let value = value {
65 | internalValidator(value)
66 | }
67 | }
68 | }
69 |
70 | public func binaryValidator(minLength: Int?, maxLength: Int?) -> (Data) -> Void {
71 | { (value: Data) -> Void in
72 | let length = value.count
73 | if let minLength = minLength {
74 | _assertFunc(length >= minLength, "\"\(value)\" must be at least \(minLength) bytes")
75 | }
76 |
77 | if let maxLength = maxLength {
78 | _assertFunc(length <= maxLength, "\"\(value)\" must be at most \(maxLength) bytes")
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/TeamLogRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Routes for the team_log namespace
10 | /// For Objective-C compatible routes see DBTeamLogRoutes
11 | public class TeamLogRoutes: DropboxTransportClientOwning {
12 | public let client: DropboxTransportClient
13 | required init(client: DropboxTransportClient) {
14 | self.client = client
15 | }
16 |
17 | /// Retrieves team events. If the result's hasMore in GetTeamEventsResult field is true, call getEventsContinue with
18 | /// the returned cursor to retrieve more entries. If end_time is not specified in your request, you may use the
19 | /// returned cursor to poll getEventsContinue for new events. Many attributes note 'may be missing due to
20 | /// historical data gap'. Note that the file_operations category and & analogous paper events are not available
21 | /// on all Dropbox Business plans /business/plans-comparison. Use features/get_values
22 | /// /developers/documentation/http/teams#team-features-get_values to check for this feature. Permission : Team
23 | /// Auditing.
24 | ///
25 | /// - scope: events.read
26 | ///
27 | /// - parameter limit: The maximal number of results to return per call. Note that some calls may not return limit
28 | /// number of events, and may even return no events, even with `has_more` set to true. In this case, callers
29 | /// should fetch again using getEventsContinue.
30 | /// - parameter accountId: Filter the events by account ID. Return only events with this account_id as either Actor,
31 | /// Context, or Participants.
32 | /// - parameter time: Filter by time range.
33 | /// - parameter category: Filter the returned events to a single category. Note that category shouldn't be provided
34 | /// together with event_type.
35 | /// - parameter eventType: Filter the returned events to a single event type. Note that event_type shouldn't be
36 | /// provided together with category.
37 | ///
38 | /// - returns: Through the response callback, the caller will receive a `TeamLog.GetTeamEventsResult` object on
39 | /// success or a `TeamLog.GetTeamEventsError` object on failure.
40 | @discardableResult public func getEvents(
41 | limit: UInt32 = 1_000,
42 | accountId: String? = nil,
43 | time: TeamCommon.TimeRange? = nil,
44 | category: TeamLog.EventCategory? = nil,
45 | eventType: TeamLog.EventTypeArg? = nil
46 | ) -> RpcRequest {
47 | let route = TeamLog.getEvents
48 | let serverArgs = TeamLog.GetTeamEventsArg(limit: limit, accountId: accountId, time: time, category: category, eventType: eventType)
49 | return client.request(route, serverArgs: serverArgs)
50 | }
51 |
52 | /// Once a cursor has been retrieved from getEvents, use this to paginate through all events. Permission : Team
53 | /// Auditing.
54 | ///
55 | /// - scope: events.read
56 | ///
57 | /// - parameter cursor: Indicates from what point to get the next set of events.
58 | ///
59 | /// - returns: Through the response callback, the caller will receive a `TeamLog.GetTeamEventsResult` object on
60 | /// success or a `TeamLog.GetTeamEventsContinueError` object on failure.
61 | @discardableResult public func getEventsContinue(cursor: String)
62 | -> RpcRequest {
63 | let route = TeamLog.getEventsContinue
64 | let serverArgs = TeamLog.GetTeamEventsContinueArg(cursor: cursor)
65 | return client.request(route, serverArgs: serverArgs)
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Generated/UsersCommon.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 |
9 | /// Datatypes and serializers for the users_common namespace
10 | public class UsersCommon {
11 | /// What type of account this user has.
12 | public enum AccountType: CustomStringConvertible, JSONRepresentable {
13 | /// The basic account type.
14 | case basic
15 | /// The Dropbox Pro account type.
16 | case pro
17 | /// The Dropbox Business account type.
18 | case business
19 |
20 | func json() throws -> JSON {
21 | try AccountTypeSerializer().serialize(self)
22 | }
23 |
24 | public var description: String {
25 | do {
26 | return "\(SerializeUtil.prepareJSONForSerialization(try AccountTypeSerializer().serialize(self)))"
27 | } catch {
28 | return "Failed to generate description for AccountType: \(error)"
29 | }
30 | }
31 | }
32 |
33 | public class AccountTypeSerializer: JSONSerializer {
34 | public init() {}
35 | public func serialize(_ value: AccountType) throws -> JSON {
36 | switch value {
37 | case .basic:
38 | var d = [String: JSON]()
39 | d[".tag"] = .str("basic")
40 | return .dictionary(d)
41 | case .pro:
42 | var d = [String: JSON]()
43 | d[".tag"] = .str("pro")
44 | return .dictionary(d)
45 | case .business:
46 | var d = [String: JSON]()
47 | d[".tag"] = .str("business")
48 | return .dictionary(d)
49 | }
50 | }
51 |
52 | public func deserialize(_ json: JSON) throws -> AccountType {
53 | switch json {
54 | case .dictionary(let d):
55 | let tag = try Serialization.getTag(d)
56 | switch tag {
57 | case "basic":
58 | return AccountType.basic
59 | case "pro":
60 | return AccountType.pro
61 | case "business":
62 | return AccountType.business
63 | default:
64 | throw JSONSerializerError.unknownTag(type: AccountType.self, json: json, tag: tag)
65 | }
66 | default:
67 | throw JSONSerializerError.deserializeError(type: AccountType.self, json: json)
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/BackgroundClientSetupInfo.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2023 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | public class DefaultBackgroundExtensionSessionCreationInfo {
8 | let backgroundSessionIdentifier: String
9 | let sharedContainerIdentifier: String
10 |
11 | public init(backgroundSessionIdentifier: String, sharedContainerIdentifier: String) {
12 | self.backgroundSessionIdentifier = backgroundSessionIdentifier
13 | self.sharedContainerIdentifier = sharedContainerIdentifier
14 | }
15 | }
16 |
17 | public class CustomBackgroundExtensionSessionCreationInfo {
18 | let backgroundTransportClient: DropboxTransportClient?
19 | let backgroundSessionConfiguration: NetworkSessionConfiguration?
20 |
21 | var backgroundSessionIdentifier: String? {
22 | if let backgroundTransportClient = backgroundTransportClient {
23 | return backgroundTransportClient.identifier
24 | } else {
25 | return backgroundSessionConfiguration?.identifier
26 | }
27 | }
28 |
29 | public init(backgroundTransportClient: DropboxTransportClient?) {
30 | self.backgroundTransportClient = backgroundTransportClient
31 | self.backgroundSessionConfiguration = nil
32 | }
33 |
34 | public init(backgroundSessionConfiguration: NetworkSessionConfiguration?) {
35 | self.backgroundTransportClient = nil
36 | self.backgroundSessionConfiguration = backgroundSessionConfiguration
37 | }
38 | }
39 |
40 | public class BackgroundExtensionSessionCreationInfo {
41 | let defaultInfo: DefaultBackgroundExtensionSessionCreationInfo?
42 | let customInfo: CustomBackgroundExtensionSessionCreationInfo?
43 |
44 | var identifier: String? {
45 | if let defaultInfo = defaultInfo {
46 | return defaultInfo.backgroundSessionIdentifier
47 | } else {
48 | return customInfo?.backgroundSessionIdentifier
49 | }
50 | }
51 |
52 | public init(defaultInfo: DefaultBackgroundExtensionSessionCreationInfo) {
53 | self.defaultInfo = defaultInfo
54 | self.customInfo = nil
55 | }
56 |
57 | public init(customInfo: CustomBackgroundExtensionSessionCreationInfo) {
58 | self.defaultInfo = nil
59 | self.customInfo = customInfo
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/CertificatePinning.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | public enum AuthChallenge {
8 | public typealias Handler = (URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?)
9 | }
10 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/Custom/CustomTasks.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | public class BatchUploadTask {
8 | let uploadData: BatchUploadData
9 |
10 | init(uploadData: BatchUploadData) {
11 | self.uploadData = uploadData
12 | }
13 |
14 | public func cancel() {
15 | uploadData.cancel = true
16 | uploadData.startRequests.values.forEach { $0.cancel() }
17 | uploadData.appendRequests.values.forEach { $0.cancel() }
18 | uploadData.finishRequest?.cancel()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/DropboxAppClient.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | /// The client for the App API. Call routes using the namespaces inside this object (inherited from parent).
8 |
9 | public class DropboxAppClient: DropboxAppBase {
10 | private var transportClient: DropboxTransportClient
11 |
12 | /// Designated Initializer.
13 | ///
14 | /// - Parameter transportClient: The underlying DropboxTransportClient to make API calls.
15 | public init(transportClient: DropboxTransportClient) {
16 | self.transportClient = transportClient
17 | super.init(client: transportClient)
18 | }
19 |
20 | /// Initializer used by DropboxTransportClientOwning in tests.
21 | ///
22 | /// - Parameter client: The underlying DropboxTransportClient to make API calls.
23 | required convenience init(client: DropboxTransportClient) {
24 | self.init(transportClient: client)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/DropboxTeamClient.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | /// The client for the Business API. Call routes using the namespaces inside this object (inherited from parent).
8 |
9 | public class DropboxTeamClient: DropboxTeamBase {
10 | public let accessTokenProvider: AccessTokenProvider
11 |
12 | /// Initialize a client with a static accessToken string.
13 | /// Use this method if your access token is long-lived.
14 | ///
15 | /// - Parameter accessToken: Static access token string.
16 | public convenience init(accessToken: String) {
17 | let transportClient = DropboxTransportClientImpl(accessToken: accessToken)
18 | self.init(transportClient: transportClient)
19 | }
20 |
21 | /// Initialize a client with an `AccessTokenProvider`.
22 | /// Use this method if your access token is short-lived.
23 | /// See `ShortLivedAccessTokenProvider` for a default implementation.
24 | ///
25 | /// - Parameters:
26 | /// - accessTokenProvider: Access token provider that wraps a short-lived token and its refresh logic.
27 | /// - sessionConfiguration: Optional custom network session configuration
28 | public convenience init(
29 | accessTokenProvider: AccessTokenProvider,
30 | sessionConfiguration: NetworkSessionConfiguration? = nil
31 | ) {
32 | let transportClient = DropboxTransportClientImpl(accessTokenProvider: accessTokenProvider, sessionConfiguration: sessionConfiguration)
33 | self.init(transportClient: transportClient)
34 | }
35 |
36 | /// Initialize a client with an `DropboxAccessToken`.
37 | ///
38 | /// - Parameters:
39 | /// - accessToken: The token itself, could be long or short lived.
40 | /// - dropboxOauthManager: an oauthManager, used for creating the token provider.
41 | /// - sessionConfiguration: Optional custom network session configuration
42 | public convenience init(
43 | accessToken: DropboxAccessToken,
44 | dropboxOauthManager: DropboxOAuthManager,
45 | sessionConfiguration: NetworkSessionConfiguration? = nil
46 | ) {
47 | let accessTokenProvider = dropboxOauthManager.accessTokenProviderForToken(accessToken)
48 | let transportClient = DropboxTransportClientImpl(accessTokenProvider: accessTokenProvider, sessionConfiguration: sessionConfiguration)
49 | self.init(transportClient: transportClient)
50 | }
51 |
52 | /// Designated Initializer.
53 | ///
54 | /// - Parameter transportClient: The underlying DropboxTransportClient to make API calls.
55 | public init(transportClient: DropboxTransportClient) {
56 | guard let accessTokenProvider = transportClient.accessTokenProvider else {
57 | fatalError("misconfigured user auth transport client")
58 | }
59 | self.accessTokenProvider = accessTokenProvider
60 | super.init(client: transportClient)
61 | }
62 |
63 | /// Initializer used by DropboxTransportClientOwning in tests.
64 | ///
65 | /// - Parameter client: The underlying DropboxTransportClient to make API calls.
66 | required convenience init(client: DropboxTransportClient) {
67 | self.init(transportClient: client)
68 | }
69 |
70 | /// Creates a new DropboxClient instance for the team member id.
71 | ///
72 | /// - Parameter memberId: Team member id.
73 | /// - Returns: A new DropboxClient instance that can be used to call APIs on the team member's behalf.
74 | public func asMember(_ memberId: String) -> DropboxClient {
75 | DropboxClient(accessTokenProvider: accessTokenProvider, selectUser: memberId)
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/DropboxTransportClientInterface.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2023 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | public protocol DropboxTransportClient {
8 | var selectUser: String? { get set }
9 | var pathRoot: Common.PathRoot? { get set }
10 | var didFinishBackgroundEvents: (() -> Void)? { get set }
11 | var accessTokenProvider: AccessTokenProvider? { get set }
12 | var isBackgroundClient: Bool { get }
13 |
14 | static var serializeOnBackgroundThread: Bool { get set }
15 |
16 | var identifier: String? { get }
17 |
18 | func request(
19 | _ route: Route
20 | ) -> RpcRequest
21 |
22 | func request(
23 | _ route: Route,
24 | serverArgs: ASerial.ValueType?
25 | ) -> RpcRequest
26 |
27 | func request(
28 | _ route: Route,
29 | serverArgs: ASerial.ValueType,
30 | input: UploadBody
31 | ) -> UploadRequest
32 |
33 | func request(
34 | _ route: Route,
35 | serverArgs: ASerial.ValueType,
36 | overwrite: Bool,
37 | destination: URL
38 | ) -> DownloadRequestFile
39 |
40 | func request(
41 | _ route: Route,
42 | serverArgs: ASerial.ValueType
43 | ) -> DownloadRequestMemory
44 |
45 | func shutdown()
46 | }
47 |
48 | protocol DropboxTransportClientInternal: DropboxTransportClient {
49 | var manager: NetworkSessionManager { get }
50 | var longpollManager: NetworkSessionManager { get }
51 |
52 | func reconnectRequest(
53 | _ route: Route,
54 | apiRequest: ApiRequest
55 | ) -> UploadRequest
56 |
57 | func reconnectRequest(
58 | _ route: Route,
59 | apiRequest: ApiRequest,
60 | overwrite: Bool,
61 | destination: URL
62 | ) -> DownloadRequestFile
63 | }
64 |
65 | typealias SessionCreation = (NetworkSessionConfiguration, CombinedURLSessionDelegate, OperationQueue) -> NetworkSession
66 | let DefaultSessionCreation: SessionCreation = { configuration, delegate, queue in
67 | URLSession(configuration: configuration.urlSessionConfiguration, delegate: delegate, delegateQueue: queue)
68 | }
69 |
70 | public typealias HeadersForRouteRequest = (RouteHost) -> [String: String]
71 |
72 | public enum AuthStrategy {
73 | case accessToken(AccessTokenProvider)
74 | case appKeyAndSecret(String, String)
75 |
76 | var accessTokenHeaderValue: String? {
77 | if case .accessToken(let provider) = self {
78 | return "Bearer \(provider.accessToken)"
79 | }
80 | return nil
81 | }
82 |
83 | var appKeyAndSecretHeaderValue: String? {
84 | if case .appKeyAndSecret(let appKey, let appSecret) = self {
85 | let authString = "\(appKey):\(appSecret)"
86 | let authData = authString.data(using: .utf8) ?? .init()
87 | return "Basic \(authData.base64EncodedString())"
88 | }
89 | return nil
90 | }
91 |
92 | var accessTokenProvider: AccessTokenProvider? {
93 | if case .accessToken(let provider) = self {
94 | return provider
95 | }
96 | return nil
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/FilesAcccess.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2022 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | import Foundation
6 |
7 | public enum FilesAccessError: Error {
8 | case errorMovingToTempLocation(Error)
9 | case errorMovingFromTempLocation(Error)
10 | case errorMovingFromTempLocationDestinationCollision(String)
11 | case couldNotReadErrorDataAtUrl(Error)
12 | }
13 |
14 | @objc(DBFilesAccess)
15 | public protocol FilesAccess {
16 | func moveFileToTemporaryLocation(from networkSessionTemporaryLocation: URL) throws -> URL
17 | func moveFile(from temporaryLocation: URL, to finalUrl: URL, overwrite: Bool) throws -> URL
18 | func errorData(from location: URL) throws -> Data
19 | }
20 |
21 | public class FilesAccessImpl: FilesAccess {
22 | var fileManager: FileManagerProtocol
23 | let tempFolder = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
24 |
25 | public convenience init() {
26 | self.init(fileManager: FileManager.default)
27 | }
28 |
29 | init(fileManager: FileManagerProtocol) {
30 | self.fileManager = fileManager
31 | setupDirectories()
32 | }
33 |
34 | private func setupDirectories() {
35 | if !fileManager.fileExists(atPath: tempFolder.path) {
36 | try! fileManager.createDirectory(at: tempFolder, withIntermediateDirectories: true, attributes: nil)
37 | }
38 | }
39 |
40 | public func moveFileToTemporaryLocation(from networkSessionTemporaryLocation: URL) throws -> URL {
41 | do {
42 | let tempOutputURL = tempFolder.appendingPathComponent(UUID().uuidString)
43 | try fileManager.moveItem(at: networkSessionTemporaryLocation, to: tempOutputURL)
44 | return tempOutputURL
45 | } catch {
46 | throw FilesAccessError.errorMovingToTempLocation(error)
47 | }
48 | }
49 |
50 | public func moveFile(from temporaryLocation: URL, to finalUrl: URL, overwrite: Bool) throws -> URL {
51 | if fileManager.fileExists(atPath: finalUrl.path) {
52 | if overwrite {
53 | do {
54 | try fileManager.removeItem(at: finalUrl)
55 | } catch {
56 | throw FilesAccessError.errorMovingFromTempLocation(error)
57 | }
58 | } else {
59 | throw FilesAccessError.errorMovingFromTempLocationDestinationCollision(finalUrl.path)
60 | }
61 | }
62 |
63 | do {
64 | try fileManager.moveItem(at: temporaryLocation, to: finalUrl)
65 | return finalUrl
66 | } catch {
67 | throw FilesAccessError.errorMovingFromTempLocation(error)
68 | }
69 | }
70 |
71 | public func errorData(from location: URL) throws -> Data {
72 | do {
73 | let data = try fileManager.contents(atPath: location.path).orThrow()
74 | try fileManager.removeItem(at: location)
75 | return data
76 | } catch {
77 | throw FilesAccessError.couldNotReadErrorDataAtUrl(error)
78 | }
79 | }
80 | }
81 |
82 | protocol FileManagerProtocol {
83 | func fileExists(atPath: String) -> Bool
84 | func contents(atPath: String) -> Data?
85 | func createDirectory(at: URL, withIntermediateDirectories: Bool, attributes: [FileAttributeKey: Any]?) throws
86 | func moveItem(atPath: String, toPath: String) throws
87 | func moveItem(at: URL, to: URL) throws
88 | func removeItem(at: URL) throws
89 | }
90 |
91 | extension FileManager: FileManagerProtocol {}
92 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/GlobalErrorResponseHandler.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /// Similar to `DBGlobalErrorResponseHandler` in the Objc SDK
4 | /// It does not have special handling for route errors, which end up type-erased right now
5 | /// It also does not allow you to easily retry requests yet, like Objc's does.
6 | /// Call `registerGlobalErrorHandler` to register a global error handler callback
7 | /// Call `deregisterGlobalErrorHandler` to deregister it
8 | /// Call `deregisterAllGlobalErrorHandlers` to deregister all global error handler callbacks
9 | public class GlobalErrorResponseHandler {
10 | /// Singleton instance of `GlobalErrorResponseHandler`
11 | public static var shared = { GlobalErrorResponseHandler() }()
12 |
13 | private struct Handler {
14 | let callback: (CallError) -> Void
15 | let queue: OperationQueue
16 | }
17 |
18 | // Locked state
19 | private struct State {
20 | var handlers: [String:Handler] = [:]
21 | }
22 |
23 | private var state = UnfairLock(value: State())
24 |
25 | internal init() { }
26 |
27 | internal func reportGlobalError(_ error: CallError) {
28 | state.read { lockedState in
29 | lockedState.handlers.forEach { _, handler in
30 | handler.queue.addOperation {
31 | handler.callback(error)
32 | }
33 | }
34 | }
35 | }
36 |
37 |
38 | /// Register a callback to be called in addition to the normal completion handler for a request.
39 | /// You can use the callback to accomplish global error handling, such as logging errors or logging a user out after an `AuthError`.
40 | /// - Parameters:
41 | /// - callback: The function you'd like called when an error occurs, it is provided a type-erased `CallError` that you can switch on. If you know the specific route error type you want to look for, you can unbox and cast the contained route error value to that type, in the case of a route error.
42 | /// - queue: The queue on which the callback should be called. Defaults to the main queue via `OperationQueue.main`.
43 | /// - Returns: A key you can use to deregister the callback later. It's just a UUID string.
44 | @discardableResult
45 | public func registerGlobalErrorHandler(_ callback: @escaping (CallError) -> Void, queue: OperationQueue = .main) -> String {
46 | let key = UUID().uuidString
47 | state.mutate { lockedState in
48 | lockedState.handlers[key] = Handler(callback: callback, queue: queue)
49 | }
50 | return key
51 | }
52 |
53 |
54 | /// Remove a global error handler callback by its key
55 | /// - Parameter key: The key returned when you registered the callback
56 | public func deregisterGlobalErrorHandler(key: String) {
57 | state.mutate { lockedState in
58 | lockedState.handlers[key] = nil
59 | }
60 | }
61 |
62 |
63 | /// Remove all global error handler callbacks, regardless of key.
64 | public func deregisterAllGlobalErrorHandlers() {
65 | state.mutate { lockedState in
66 | lockedState.handlers = [:]
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/NetworkSession/Mocks/MockNetworkSession.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2022 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | import Foundation
6 |
7 | class MockNetworkSession: NetworkSession {
8 | var identifier: String?
9 |
10 | init() {}
11 |
12 | required init(configuration: URLSessionConfiguration) {
13 | fatalError()
14 | }
15 |
16 | var tasksPendingReconnection: [NetworkTask] = []
17 | var tasks: [NetworkTaskTag: NetworkTask] = [:]
18 | var mockInputs: [NetworkTaskTag: MockInput] = [:]
19 |
20 | var invalidateCalled = false
21 |
22 | func dataTask(request: URLRequest, networkTaskTag: NetworkTaskTag?) -> NetworkDataTask {
23 | register(
24 | task: MockNetworkTaskDelegate(request: request),
25 | networkTaskTag: networkTaskTag
26 | )
27 | }
28 |
29 | func dataTask(request: URLRequest, networkTaskTag: NetworkTaskTag?, completionHandler: @escaping NetworkDataTaskCompletion) -> NetworkDataTask {
30 | register(
31 | task: MockNetworkDataTaskCompletion(
32 | request: request,
33 | mockInput: { [weak self] in
34 | networkTaskTag.flatMap { self?.mockInputs[$0] }
35 | },
36 | completionHandler: completionHandler
37 | ),
38 | networkTaskTag: networkTaskTag
39 | )
40 | }
41 |
42 | func uploadTaskData(request: URLRequest, data: Data, networkTaskTag: NetworkTaskTag?) -> NetworkUploadTask {
43 | register(
44 | task: MockNetworkTaskDelegate(request: request),
45 | networkTaskTag: networkTaskTag
46 | )
47 | }
48 |
49 | func uploadTaskStream(request: URLRequest, networkTaskTag: NetworkTaskTag?) -> NetworkUploadTask {
50 | register(
51 | task: MockNetworkTaskDelegate(request: request),
52 | networkTaskTag: networkTaskTag
53 | )
54 | }
55 |
56 | func uploadTaskFile(request: URLRequest, file: URL, networkTaskTag: NetworkTaskTag?) -> NetworkUploadTask {
57 | register(
58 | task: MockNetworkTaskDelegate(request: request),
59 | networkTaskTag: networkTaskTag
60 | )
61 | }
62 |
63 | func downloadTask(request: URLRequest, networkTaskTag: NetworkTaskTag?) -> NetworkDownloadTask {
64 | register(
65 | task: MockNetworkTaskDelegate(request: request),
66 | networkTaskTag: networkTaskTag
67 | )
68 | }
69 |
70 | func register(task: T, networkTaskTag: NetworkTaskTag?) -> T {
71 | tasks[networkTaskTag ?? UUID().uuidString] = task
72 | return task
73 | }
74 |
75 | func getAllNetworkTasks(completionHandler: ([NetworkTask]) -> Void) {
76 | completionHandler(tasksPendingReconnection)
77 | }
78 |
79 | func invalidateAndCancel() {
80 | invalidateCalled = true
81 | }
82 | }
83 |
84 | enum MockInput {
85 | case none
86 | case success(json: [String: Any])
87 | case downloadSuccess(json: [String: Any], downloadLocation: URL)
88 | case requestError(json: [String: Any], code: NetworkStatusCode)
89 | case routeError(json: [String: Any])
90 | case clientError(error: ClientError)
91 | }
92 |
93 | enum MockInputWithModel {
94 | case none
95 | case success(model: JSONRepresentable)
96 | case downloadSuccess(model: JSONRepresentable, downloadLocation: URL)
97 | case requestError(model: JSONRepresentable, code: NetworkStatusCode)
98 | case routeError(model: JSONRepresentable)
99 | }
100 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/NoopRequest.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2023 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | /// Used internally when a URLSessionTask cannot be constructed during shutdown
8 | class NoopApiRequest: ApiRequest {
9 | init() {}
10 |
11 | func handleCompletion(error: ClientError?) {}
12 |
13 | func handleRecieve(data: Data) {}
14 |
15 | func handleDownloadFinished(location: URL) {}
16 |
17 | func handleSentBodyData(totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {}
18 |
19 | func handleWroteDownloadData(totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {}
20 |
21 | var identifier: Int {
22 | networkTask?.taskIdentifier ?? -1
23 | }
24 |
25 | var taskDescription: String?
26 |
27 | var earliestBeginDate: Date?
28 |
29 | func setProgressHandler(_ handler: @escaping (Progress) -> Void) -> Self {
30 | self
31 | }
32 |
33 | func setCompletionHandlerProvider(queue: DispatchQueue?, completionHandlerProvider: RequestCompletionHandlerProvider) -> Self {
34 | self
35 | }
36 |
37 | func cancel() {}
38 |
39 | func setCleanupHandler(_ handler: @escaping () -> Void) {}
40 |
41 | var networkTask: NetworkTask? = NoopNetworkTask()
42 | }
43 |
44 | class NoopNetworkTask: NetworkTask {
45 | func resume() {}
46 |
47 | func cancel() {}
48 |
49 | var response: URLResponse?
50 |
51 | var error: Error?
52 |
53 | var originalRequest: URLRequest?
54 |
55 | var taskIdentifier: Int = Int.random(in: 1 ..< Int.max)
56 |
57 | var taskDescription: String?
58 |
59 | var earliestBeginDate: Date?
60 | }
61 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/OAuth/OAuthConstants.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2020 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | /// Contains the keys of URL queries and responses in auth flow.
8 | enum OAuthConstants {
9 | static let codeChallengeKey = "code_challenge"
10 | static let codeChallengeMethodKey = "code_challenge_method"
11 | static let tokenAccessTypeKey = "token_access_type"
12 | static let responseTypeKey = "response_type"
13 | static let scopeKey = "scope"
14 | static let includeGrantedScopesKey = "include_granted_scopes"
15 | static let stateKey = "state"
16 | static let extraQueryParamsKey = "extra_query_params"
17 | static let oauthCodeKey = "oauth_code"
18 | static let oauthTokenKey = "oauth_token"
19 | static let oauthSecretKey = "oauth_token_secret"
20 | static let uidKey = "uid"
21 | static let errorKey = "error"
22 | static let errorDescription = "error_description"
23 | }
24 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/OAuth/OAuthUtils.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2020 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | /// Contains utility methods used in auth flow. e.g. method to construct URL query.
8 | enum OAuthUtils {
9 | static func createPkceCodeFlowParams(for authSession: OAuthPKCESession) -> [URLQueryItem] {
10 | var params = [URLQueryItem]()
11 | if let scopeString = authSession.scopeRequest?.scopeString {
12 | params.append(URLQueryItem(name: OAuthConstants.scopeKey, value: scopeString))
13 | }
14 | if let scopeRequest = authSession.scopeRequest, scopeRequest.includeGrantedScopes {
15 | params.append(
16 | URLQueryItem(name: OAuthConstants.includeGrantedScopesKey, value: scopeRequest.scopeType.rawValue)
17 | )
18 | }
19 | let pkceData = authSession.pkceData
20 | params.append(contentsOf: [
21 | URLQueryItem(name: OAuthConstants.codeChallengeKey, value: pkceData.codeChallenge),
22 | URLQueryItem(name: OAuthConstants.codeChallengeMethodKey, value: pkceData.codeChallengeMethod),
23 | URLQueryItem(name: OAuthConstants.tokenAccessTypeKey, value: authSession.tokenAccessType),
24 | URLQueryItem(name: OAuthConstants.responseTypeKey, value: authSession.responseType),
25 | ])
26 | return params
27 | }
28 |
29 | /// Extracts auth response parameters from URL and removes percent encoding.
30 | /// Response parameters from DAuth via the Dropbox app are in the query component.
31 | static func extractDAuthResponseFromUrl(_ url: URL) -> [String: String] {
32 | extractQueryParamsFromUrlString(url.absoluteString)
33 | }
34 |
35 | /// Extracts auth response parameters from URL and removes percent encoding.
36 | /// Response parameters OAuth 2 code flow (RFC6749 4.1.2) are in the query component.
37 | static func extractOAuthResponseFromCodeFlowUrl(_ url: URL) -> [String: String] {
38 | extractQueryParamsFromUrlString(url.absoluteString)
39 | }
40 |
41 | /// Extracts auth response parameters from URL and removes percent encoding.
42 | /// Response parameters from OAuth 2 token flow (RFC6749 4.2.2) are in the fragment component.
43 | static func extractOAuthResponseFromTokenFlowUrl(_ url: URL) -> [String: String] {
44 | guard let urlComponents = URLComponents(string: url.absoluteString),
45 | let responseString = urlComponents.fragment else {
46 | return [:]
47 | }
48 | // Create a query only URL string and extract its individual query parameters.
49 | return extractQueryParamsFromUrlString("?\(responseString)")
50 | }
51 |
52 | /// Extracts query parameters from URL and removes percent encoding.
53 | private static func extractQueryParamsFromUrlString(_ urlString: String) -> [String: String] {
54 | guard let urlComponents = URLComponents(string: urlString),
55 | let queryItems = urlComponents.queryItems else {
56 | return [:]
57 | }
58 | return queryItems.reduce(into: [String: String]()) { result, queryItem in
59 | result[queryItem.name] = queryItem.value
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/OAuth/Reachability.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2022 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | import Foundation
6 | import SystemConfiguration
7 |
8 | class Reachability {
9 | /// From http://stackoverflow.com/questions/25623272/how-to-use-scnetworkreachability-in-swift/25623647#25623647.
10 | ///
11 | /// This method uses `SCNetworkReachabilityCreateWithAddress` to create a reference to monitor the example host
12 | /// defined by our zeroed `zeroAddress` struct. From this reference, we can extract status flags regarding the
13 | /// reachability of this host, using `SCNetworkReachabilityGetFlags`.
14 |
15 | class func connectedToNetwork() -> Bool {
16 | var zeroAddress = sockaddr_in()
17 | zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
18 | zeroAddress.sin_family = sa_family_t(AF_INET)
19 |
20 | guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
21 | $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
22 | SCNetworkReachabilityCreateWithAddress(nil, $0)
23 | }
24 | }) else {
25 | return false
26 | }
27 |
28 | var flags: SCNetworkReachabilityFlags = []
29 | if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
30 | return false
31 | }
32 |
33 | let isReachable = flags.contains(.reachable)
34 | let needsConnection = flags.contains(.connectionRequired)
35 | return (isReachable && !needsConnection)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/Request+Async.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2023 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | import Foundation
6 |
7 | public protocol HasRequestResponse {
8 | associatedtype ValueType
9 | associatedtype ESerial: JSONSerializer
10 |
11 | @discardableResult
12 | func response(
13 | queue: DispatchQueue?,
14 | completionHandler: @escaping (ValueType?, CallError?) -> Void
15 | ) -> Self
16 | }
17 |
18 | @available(iOS 13.0, macOS 10.15, *)
19 | extension HasRequestResponse {
20 | /// Async wrapper for retrieving a request's response
21 | ///
22 | /// This could have a better name, but this avoids a collision with the other `response` methods
23 | public func responseResult(
24 | ) async -> Result> {
25 | await withCheckedContinuation { continuation in
26 | self.response(queue: nil) { result, error in
27 | if let result {
28 | continuation.resume(returning: .success(result))
29 | } else if let error {
30 | continuation.resume(returning: .failure(error))
31 | } else {
32 | // this should never happen
33 | continuation.resume(returning: .failure(.clientError(.unexpectedState)))
34 | }
35 | }
36 | }
37 | }
38 |
39 | /// Async wrapper for retrieving a request's response
40 | ///
41 | /// Same thing as `responseResult` but using async throws instead of returing a Result
42 | public func response(
43 | ) async throws -> ValueType {
44 | try await responseResult().get()
45 | }
46 | }
47 |
48 | extension RpcRequest: HasRequestResponse {}
49 | extension UploadRequest: HasRequestResponse {}
50 | extension DownloadRequestFile: HasRequestResponse {}
51 | extension DownloadRequestMemory: HasRequestResponse {}
52 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/RequestMap.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2022 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | import Foundation
6 |
7 | protocol ApiRequestBox {
8 | var value: ApiRequest? { get }
9 | init(value: ApiRequest)
10 | }
11 |
12 | class WeakApiRequestBox: ApiRequestBox {
13 | weak var value: ApiRequest?
14 | required init(value: ApiRequest) {
15 | self.value = value
16 | }
17 | }
18 |
19 | class PendingReconnectionStrongApiRequestBox: ApiRequestBox {
20 | var value: ApiRequest? {
21 | strongValue
22 | }
23 |
24 | var strongValue: ApiRequest
25 | required init(value: ApiRequest) {
26 | self.strongValue = value
27 | }
28 | }
29 |
30 | protocol RequestMap {
31 | func set(request: ApiRequest, taskIdentifier: Int)
32 | func setPendingReconnection(request: ApiRequest, taskIdentifier: Int)
33 | func getRequest(taskIdentifier: Int) -> ApiRequest?
34 | func getAllRequests() -> [ApiRequest]
35 | func getAllPendingReconnectionRequests() -> [ApiRequest]
36 | func weakifyReferencesToReconnectedRequests()
37 | func removeRequest(taskIdentifier: Int)
38 | func removeAllRequests()
39 | }
40 |
41 | class RequestMapImpl: RequestMap {
42 | private var map: [Int: ApiRequestBox] = [:]
43 | private var cleanupThreshold: Int = 250
44 |
45 | init() {}
46 |
47 | func setPendingReconnection(request: ApiRequest, taskIdentifier: Int) {
48 | map[taskIdentifier] = PendingReconnectionStrongApiRequestBox(value: request)
49 | }
50 |
51 | func set(request: ApiRequest, taskIdentifier: Int) {
52 | map[taskIdentifier] = WeakApiRequestBox(value: request)
53 |
54 | if map.count >= cleanupThreshold {
55 | cleanupEmptyBoxes()
56 | }
57 | }
58 |
59 | func getRequest(taskIdentifier: Int) -> ApiRequest? {
60 | map[taskIdentifier]?.value
61 | }
62 |
63 | func getAllRequests() -> [ApiRequest] {
64 | Array(map.values.compactMap(\.value))
65 | }
66 |
67 | func getAllPendingReconnectionRequests() -> [ApiRequest] {
68 | let isPending: (ApiRequestBox) -> Bool = { $0 is PendingReconnectionStrongApiRequestBox }
69 | return Array(map.values.filter(isPending).compactMap(\.value))
70 | }
71 |
72 | func weakifyReferencesToReconnectedRequests() {
73 | map = map.mapValues { box in
74 | if let box = box as? PendingReconnectionStrongApiRequestBox {
75 | return WeakApiRequestBox(value: box.strongValue)
76 | }
77 | return box
78 | }
79 | }
80 |
81 | func cleanupEmptyBoxes() {
82 | map = map.filter { _, box in
83 | if let box = box as? WeakApiRequestBox, box.value == nil {
84 | return false
85 | }
86 | return true
87 | }
88 | }
89 |
90 | func removeRequest(taskIdentifier: Int) {
91 | map[taskIdentifier] = nil
92 | }
93 |
94 | func removeAllRequests() {
95 | map = [:]
96 | }
97 |
98 | func __test_only_setCleanupThreshold(value: Int) {
99 | cleanupThreshold = value
100 | }
101 |
102 | var __test_only_map: [Int: ApiRequestBox] {
103 | map
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/Source/SwiftyDropbox/Shared/Handwritten/SDKConstants.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | public struct Constants {
8 | public static let versionSDK = "10.2.0"
9 | static let kCSRFKey = "kCSRFKeySwiftSDK"
10 | }
11 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Platform/SwiftyDropbox_iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 7.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 10.2.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Platform/SwiftyDropbox_macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 7.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 10.2.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSHumanReadableCopyright
22 | Copyright © 2016 Dropbox. All rights reserved.
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXAuthAppAuthRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible routes for the auth namespace
11 | /// For Swift routes see AuthAppAuthRoutes
12 | @objc
13 | public class DBXAuthAppAuthRoutes: NSObject {
14 | private let swift: AuthAppAuthRoutes
15 | init(swift: AuthAppAuthRoutes) {
16 | self.swift = swift
17 | self.client = swift.client.objc
18 | }
19 |
20 | public let client: DBXDropboxTransportClient
21 | }
22 |
23 | @objc
24 | public class DBXAuthTokenFromOauth1RpcRequest: NSObject, DBXRequest {
25 | var swift: RpcRequest
26 |
27 | init(swift: RpcRequest) {
28 | self.swift = swift
29 | }
30 |
31 | @objc
32 | @discardableResult public func response(
33 | completionHandler: @escaping (DBXAuthTokenFromOAuth1Result?, DBXAuthTokenFromOAuth1Error?, DBXCallError?) -> Void
34 | ) -> Self {
35 | response(queue: nil, completionHandler: completionHandler)
36 | }
37 |
38 | @objc
39 | @discardableResult public func response(
40 | queue: DispatchQueue?,
41 | completionHandler: @escaping (DBXAuthTokenFromOAuth1Result?, DBXAuthTokenFromOAuth1Error?, DBXCallError?) -> Void
42 | ) -> Self {
43 | swift.response(queue: queue) { result, error in
44 | var routeError: DBXAuthTokenFromOAuth1Error?
45 | var callError: DBXCallError?
46 | switch error {
47 | case .routeError(let box, _, _, _):
48 | routeError = DBXAuthTokenFromOAuth1Error(swift: box.unboxed)
49 | callError = nil
50 | default:
51 | routeError = nil
52 | callError = error?.objc
53 | }
54 |
55 | var objc: DBXAuthTokenFromOAuth1Result?
56 | if let swift = result {
57 | objc = DBXAuthTokenFromOAuth1Result(swift: swift)
58 | }
59 | completionHandler(objc, routeError, callError)
60 | }
61 | return self
62 | }
63 |
64 | @objc
65 | public var clientPersistedString: String? { swift.clientPersistedString }
66 |
67 | @available(iOS 13.0, macOS 10.13, *)
68 | @objc
69 | public var earliestBeginDate: Date? { swift.earliestBeginDate }
70 |
71 | @objc
72 | public func persistingString(string: String?) -> Self {
73 | swift.persistingString(string: string)
74 | return self
75 | }
76 |
77 | @available(iOS 13.0, macOS 10.13, *)
78 | @objc
79 | public func settingEarliestBeginDate(date: Date?) -> Self {
80 | swift.settingEarliestBeginDate(date: date)
81 | return self
82 | }
83 |
84 | @objc
85 | public func cancel() {
86 | swift.cancel()
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXAuthRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible routes for the auth namespace
11 | /// For Swift routes see AuthRoutes
12 | @objc
13 | public class DBXAuthRoutes: NSObject {
14 | private let swift: AuthRoutes
15 | init(swift: AuthRoutes) {
16 | self.swift = swift
17 | self.client = swift.client.objc
18 | }
19 |
20 | public let client: DBXDropboxTransportClient
21 |
22 | /// Disables the access token used to authenticate the call. If there is a corresponding refresh token for the
23 | /// access token, this disables that refresh token, as well as any other access tokens for that refresh token.
24 | ///
25 | ///
26 | /// - returns: Through the response callback, the caller will receive a `Void` object on success or a `Void` object
27 | /// on failure.
28 | @objc
29 | @discardableResult public func tokenRevoke() -> DBXAuthTokenRevokeRpcRequest {
30 | let swift = swift.tokenRevoke()
31 | return DBXAuthTokenRevokeRpcRequest(swift: swift)
32 | }
33 | }
34 |
35 | @objc
36 | public class DBXAuthTokenRevokeRpcRequest: NSObject, DBXRequest {
37 | var swift: RpcRequest
38 |
39 | init(swift: RpcRequest) {
40 | self.swift = swift
41 | }
42 |
43 | @objc
44 | @discardableResult public func response(
45 | completionHandler: @escaping (DBXCallError?) -> Void
46 | ) -> Self {
47 | response(queue: nil, completionHandler: completionHandler)
48 | }
49 |
50 | @objc
51 | @discardableResult public func response(
52 | queue: DispatchQueue?,
53 | completionHandler: @escaping (DBXCallError?) -> Void
54 | ) -> Self {
55 | swift.response(queue: queue) { _, error in
56 | completionHandler(error?.objc)
57 | }
58 | return self
59 | }
60 |
61 | @objc
62 | public var clientPersistedString: String? { swift.clientPersistedString }
63 |
64 | @available(iOS 13.0, macOS 10.13, *)
65 | @objc
66 | public var earliestBeginDate: Date? { swift.earliestBeginDate }
67 |
68 | @objc
69 | public func persistingString(string: String?) -> Self {
70 | swift.persistingString(string: string)
71 | return self
72 | }
73 |
74 | @available(iOS 13.0, macOS 10.13, *)
75 | @objc
76 | public func settingEarliestBeginDate(date: Date?) -> Self {
77 | swift.settingEarliestBeginDate(date: date)
78 | return self
79 | }
80 |
81 | @objc
82 | public func cancel() {
83 | swift.cancel()
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXBase.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible DropboxBase.
11 | /// For Swift see DropboxBase.
12 | @objc
13 | public class DBXDropboxBase: NSObject {
14 | let swift: DropboxBase
15 |
16 | /// Routes within the account namespace. See DBAccountRoutes for details.
17 | @objc
18 | public var account: DBXAccountRoutes!
19 | /// Routes within the auth namespace. See DBAuthRoutes for details.
20 | @objc
21 | public var auth: DBXAuthRoutes!
22 | /// Routes within the check namespace. See DBCheckRoutes for details.
23 | @objc
24 | public var check: DBXCheckRoutes!
25 | /// Routes within the contacts namespace. See DBContactsRoutes for details.
26 | @objc
27 | public var contacts: DBXContactsRoutes!
28 | /// Routes within the fileProperties namespace. See DBFilePropertiesRoutes for details.
29 | @objc
30 | public var fileProperties: DBXFilePropertiesRoutes!
31 | /// Routes within the fileRequests namespace. See DBFileRequestsRoutes for details.
32 | @objc
33 | public var fileRequests: DBXFileRequestsRoutes!
34 | /// Routes within the files namespace. See DBFilesRoutes for details.
35 | @objc
36 | public var files: DBXFilesRoutes!
37 | /// Routes within the openid namespace. See DBOpenidRoutes for details.
38 | @objc
39 | public var openid: DBXOpenidRoutes!
40 | /// Routes within the paper namespace. See DBPaperRoutes for details.
41 | @objc
42 | public var paper: DBXPaperRoutes!
43 | /// Routes within the sharing namespace. See DBSharingRoutes for details.
44 | @objc
45 | public var sharing: DBXSharingRoutes!
46 | /// Routes within the teamLog namespace. See DBTeamLogRoutes for details.
47 | @objc
48 | public var teamLog: DBXTeamLogRoutes!
49 | /// Routes within the users namespace. See DBUsersRoutes for details.
50 | @objc
51 | public var users: DBXUsersRoutes!
52 |
53 | @objc
54 | public convenience init(client: DBXDropboxTransportClient) {
55 | self.init(swiftClient: client.swift)
56 | }
57 |
58 | public init(swiftClient: DropboxTransportClient) {
59 | self.swift = DropboxBase(client: swiftClient)
60 |
61 | self.account = DBXAccountRoutes(swift: swift.account)
62 | self.auth = DBXAuthRoutes(swift: swift.auth)
63 | self.check = DBXCheckRoutes(swift: swift.check)
64 | self.contacts = DBXContactsRoutes(swift: swift.contacts)
65 | self.fileProperties = DBXFilePropertiesRoutes(swift: swift.fileProperties)
66 | self.fileRequests = DBXFileRequestsRoutes(swift: swift.fileRequests)
67 | self.files = DBXFilesRoutes(swift: swift.files)
68 | self.openid = DBXOpenidRoutes(swift: swift.openid)
69 | self.paper = DBXPaperRoutes(swift: swift.paper)
70 | self.sharing = DBXSharingRoutes(swift: swift.sharing)
71 | self.teamLog = DBXTeamLogRoutes(swift: swift.teamLog)
72 | self.users = DBXUsersRoutes(swift: swift.users)
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXBaseApp.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible DropboxAppBase.
11 | /// For Swift see DropboxAppBase.
12 | @objc
13 | public class DBXDropboxAppBase: NSObject {
14 | let swift: DropboxAppBase
15 |
16 | /// Routes within the auth namespace. See DBAuthAppAuthRoutes for details.
17 | @objc
18 | public var auth: DBXAuthAppAuthRoutes!
19 | /// Routes within the check namespace. See DBCheckAppAuthRoutes for details.
20 | @objc
21 | public var check: DBXCheckAppAuthRoutes!
22 | /// Routes within the files namespace. See DBFilesAppAuthRoutes for details.
23 | @objc
24 | public var files: DBXFilesAppAuthRoutes!
25 | /// Routes within the sharing namespace. See DBSharingAppAuthRoutes for details.
26 | @objc
27 | public var sharing: DBXSharingAppAuthRoutes!
28 |
29 | @objc
30 | public convenience init(client: DBXDropboxTransportClient) {
31 | self.init(swiftClient: client.swift)
32 | }
33 |
34 | public init(swiftClient: DropboxTransportClient) {
35 | self.swift = DropboxAppBase(client: swiftClient)
36 |
37 | self.auth = DBXAuthAppAuthRoutes(swift: swift.auth)
38 | self.check = DBXCheckAppAuthRoutes(swift: swift.check)
39 | self.files = DBXFilesAppAuthRoutes(swift: swift.files)
40 | self.sharing = DBXSharingAppAuthRoutes(swift: swift.sharing)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXBaseTeam.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible DropboxTeamBase.
11 | /// For Swift see DropboxTeamBase.
12 | @objc
13 | public class DBXDropboxTeamBase: NSObject {
14 | let swift: DropboxTeamBase
15 |
16 | /// Routes within the team namespace. See DBTeamRoutes for details.
17 | @objc
18 | public var team: DBXTeamRoutes!
19 |
20 | @objc
21 | public convenience init(client: DBXDropboxTransportClient) {
22 | self.init(swiftClient: client.swift)
23 | }
24 |
25 | public init(swiftClient: DropboxTransportClient) {
26 | self.swift = DropboxTeamBase(client: swiftClient)
27 |
28 | self.team = DBXTeamRoutes(swift: swift.team)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXCheck.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible datatypes for the check namespace
11 | /// For Swift see check
12 |
13 | /// Contains the arguments to be sent to the Dropbox servers.
14 | @objc
15 | public class DBXCheckEchoArg: NSObject {
16 | /// The string that you'd like to be echoed back to you.
17 | @objc
18 | public var query: String { swift.query }
19 |
20 | @objc
21 | public init(query: String) {
22 | self.swift = Check.EchoArg(query: query)
23 | }
24 |
25 | let swift: Check.EchoArg
26 |
27 | public init(swift: Check.EchoArg) {
28 | self.swift = swift
29 | }
30 |
31 | @objc
32 | public override var description: String { swift.description }
33 | }
34 |
35 | /// EchoResult contains the result returned from the Dropbox servers.
36 | @objc
37 | public class DBXCheckEchoResult: NSObject {
38 | /// If everything worked correctly, this would be the same as query.
39 | @objc
40 | public var result: String { swift.result }
41 |
42 | @objc
43 | public init(result: String) {
44 | self.swift = Check.EchoResult(result: result)
45 | }
46 |
47 | let swift: Check.EchoResult
48 |
49 | public init(swift: Check.EchoResult) {
50 | self.swift = swift
51 | }
52 |
53 | @objc
54 | public override var description: String { swift.description }
55 | }
56 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXContacts.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible datatypes for the contacts namespace
11 | /// For Swift see contacts
12 |
13 | /// Objective-C compatible DeleteManualContactsArg struct
14 | @objc
15 | public class DBXContactsDeleteManualContactsArg: NSObject {
16 | /// List of manually added contacts to be deleted.
17 | @objc
18 | public var emailAddresses: [String] { swift.emailAddresses }
19 |
20 | @objc
21 | public init(emailAddresses: [String]) {
22 | self.swift = Contacts.DeleteManualContactsArg(emailAddresses: emailAddresses)
23 | }
24 |
25 | let swift: Contacts.DeleteManualContactsArg
26 |
27 | public init(swift: Contacts.DeleteManualContactsArg) {
28 | self.swift = swift
29 | }
30 |
31 | @objc
32 | public override var description: String { swift.description }
33 | }
34 |
35 | /// Objective-C compatible DeleteManualContactsError union
36 | @objc
37 | public class DBXContactsDeleteManualContactsError: NSObject {
38 | let swift: Contacts.DeleteManualContactsError
39 |
40 | public init(swift: Contacts.DeleteManualContactsError) {
41 | self.swift = swift
42 | }
43 |
44 | public static func factory(swift: Contacts.DeleteManualContactsError) -> DBXContactsDeleteManualContactsError {
45 | switch swift {
46 | case .contactsNotFound(let swiftArg):
47 | let arg = swiftArg
48 | return DBXContactsDeleteManualContactsErrorContactsNotFound(arg)
49 | case .other:
50 | return DBXContactsDeleteManualContactsErrorOther()
51 | }
52 | }
53 |
54 | @objc
55 | public override var description: String { swift.description }
56 |
57 | @objc
58 | public var asContactsNotFound: DBXContactsDeleteManualContactsErrorContactsNotFound? {
59 | self as? DBXContactsDeleteManualContactsErrorContactsNotFound
60 | }
61 |
62 | @objc
63 | public var asOther: DBXContactsDeleteManualContactsErrorOther? {
64 | self as? DBXContactsDeleteManualContactsErrorOther
65 | }
66 | }
67 |
68 | /// Can't delete contacts from this list. Make sure the list only has manually added contacts. The deletion was
69 | /// cancelled.
70 | @objc
71 | public class DBXContactsDeleteManualContactsErrorContactsNotFound: DBXContactsDeleteManualContactsError {
72 | @objc
73 | public var contactsNotFound: [String]
74 |
75 | @objc
76 | public init(_ arg: [String]) {
77 | self.contactsNotFound = arg
78 | let swift = Contacts.DeleteManualContactsError.contactsNotFound(arg)
79 | super.init(swift: swift)
80 | }
81 | }
82 |
83 | /// An unspecified error.
84 | @objc
85 | public class DBXContactsDeleteManualContactsErrorOther: DBXContactsDeleteManualContactsError {
86 | @objc
87 | public init() {
88 | let swift = Contacts.DeleteManualContactsError.other
89 | super.init(swift: swift)
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXDropboxAppBaseRequestBox.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | extension DropboxAppBaseRequestBox {
11 | var objc: DBXRequest {
12 | if case .files_getThumbnailV2(let swift) = self {
13 | return DBXFilesGetThumbnailDownloadRequestFileV2(swift: swift)
14 | } else {
15 | fatalError("For Obj-C compatibility, add this route to the Objective-C compatibility module allow-list")
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXDropboxBaseRequestBox.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | extension DropboxBaseRequestBox {
11 | var objc: DBXRequest {
12 | if case .files_alphaUpload(let swift) = self {
13 | return DBXFilesAlphaUploadUploadRequest(swift: swift)
14 | }
15 | if case .files_download(let swift) = self {
16 | return DBXFilesDownloadDownloadRequestFile(swift: swift)
17 | }
18 | if case .files_downloadZip(let swift) = self {
19 | return DBXFilesDownloadZipDownloadRequestFile(swift: swift)
20 | }
21 | if case .files_export(let swift) = self {
22 | return DBXFilesExportDownloadRequestFile(swift: swift)
23 | }
24 | if case .files_getPreview(let swift) = self {
25 | return DBXFilesGetPreviewDownloadRequestFile(swift: swift)
26 | }
27 | if case .files_getThumbnail(let swift) = self {
28 | return DBXFilesGetThumbnailDownloadRequestFile(swift: swift)
29 | }
30 | if case .files_getThumbnailV2(let swift) = self {
31 | return DBXFilesGetThumbnailDownloadRequestFileV2(swift: swift)
32 | }
33 | if case .files_paperCreate(let swift) = self {
34 | return DBXFilesPaperCreateUploadRequest(swift: swift)
35 | }
36 | if case .files_paperUpdate(let swift) = self {
37 | return DBXFilesPaperUpdateUploadRequest(swift: swift)
38 | }
39 | if case .files_upload(let swift) = self {
40 | return DBXFilesUploadUploadRequest(swift: swift)
41 | }
42 | if case .files_uploadSessionAppend(let swift) = self {
43 | return DBXFilesUploadSessionAppendUploadRequest(swift: swift)
44 | }
45 | if case .files_uploadSessionAppendV2(let swift) = self {
46 | return DBXFilesUploadSessionAppendUploadRequestV2(swift: swift)
47 | }
48 | if case .files_uploadSessionFinish(let swift) = self {
49 | return DBXFilesUploadSessionFinishUploadRequest(swift: swift)
50 | }
51 | if case .files_uploadSessionStart(let swift) = self {
52 | return DBXFilesUploadSessionStartUploadRequest(swift: swift)
53 | }
54 | if case .paper_docsCreate(let swift) = self {
55 | return DBXPaperDocsCreateUploadRequest(swift: swift)
56 | }
57 | if case .paper_docsDownload(let swift) = self {
58 | return DBXPaperDocsDownloadDownloadRequestFile(swift: swift)
59 | }
60 | if case .paper_docsUpdate(let swift) = self {
61 | return DBXPaperDocsUpdateUploadRequest(swift: swift)
62 | }
63 | if case .sharing_getSharedLinkFile(let swift) = self {
64 | return DBXSharingGetSharedLinkFileDownloadRequestFile(swift: swift)
65 | } else {
66 | fatalError("For Obj-C compatibility, add this route to the Objective-C compatibility module allow-list")
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXOpenidRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible routes for the openid namespace
11 | /// For Swift routes see OpenidRoutes
12 | @objc
13 | public class DBXOpenidRoutes: NSObject {
14 | private let swift: OpenidRoutes
15 | init(swift: OpenidRoutes) {
16 | self.swift = swift
17 | self.client = swift.client.objc
18 | }
19 |
20 | public let client: DBXDropboxTransportClient
21 |
22 | /// This route is used for refreshing the info that is found in the id_token during the OIDC flow. This route
23 | /// doesn't require any arguments and will use the scopes approved for the given access token.
24 | ///
25 | /// - scope: openid
26 | ///
27 | ///
28 | /// - returns: Through the response callback, the caller will receive a `Openid.UserInfoResult` object on success or
29 | /// a `Openid.UserInfoError` object on failure.
30 | @objc
31 | @discardableResult public func userinfo() -> DBXOpenidUserinfoRpcRequest {
32 | let swift = swift.userinfo()
33 | return DBXOpenidUserinfoRpcRequest(swift: swift)
34 | }
35 | }
36 |
37 | @objc
38 | public class DBXOpenidUserinfoRpcRequest: NSObject, DBXRequest {
39 | var swift: RpcRequest
40 |
41 | init(swift: RpcRequest) {
42 | self.swift = swift
43 | }
44 |
45 | @objc
46 | @discardableResult public func response(
47 | completionHandler: @escaping (DBXOpenidUserInfoResult?, DBXOpenidUserInfoError?, DBXCallError?) -> Void
48 | ) -> Self {
49 | response(queue: nil, completionHandler: completionHandler)
50 | }
51 |
52 | @objc
53 | @discardableResult public func response(
54 | queue: DispatchQueue?,
55 | completionHandler: @escaping (DBXOpenidUserInfoResult?, DBXOpenidUserInfoError?, DBXCallError?) -> Void
56 | ) -> Self {
57 | swift.response(queue: queue) { result, error in
58 | var routeError: DBXOpenidUserInfoError?
59 | var callError: DBXCallError?
60 | switch error {
61 | case .routeError(let box, _, _, _):
62 | routeError = DBXOpenidUserInfoError(swift: box.unboxed)
63 | callError = nil
64 | default:
65 | routeError = nil
66 | callError = error?.objc
67 | }
68 |
69 | var objc: DBXOpenidUserInfoResult?
70 | if let swift = result {
71 | objc = DBXOpenidUserInfoResult(swift: swift)
72 | }
73 | completionHandler(objc, routeError, callError)
74 | }
75 | return self
76 | }
77 |
78 | @objc
79 | public var clientPersistedString: String? { swift.clientPersistedString }
80 |
81 | @available(iOS 13.0, macOS 10.13, *)
82 | @objc
83 | public var earliestBeginDate: Date? { swift.earliestBeginDate }
84 |
85 | @objc
86 | public func persistingString(string: String?) -> Self {
87 | swift.persistingString(string: string)
88 | return self
89 | }
90 |
91 | @available(iOS 13.0, macOS 10.13, *)
92 | @objc
93 | public func settingEarliestBeginDate(date: Date?) -> Self {
94 | swift.settingEarliestBeginDate(date: date)
95 | return self
96 | }
97 |
98 | @objc
99 | public func cancel() {
100 | swift.cancel()
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXSecondaryEmails.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible datatypes for the secondary_emails namespace
11 | /// For Swift see secondary_emails
12 |
13 | /// Objective-C compatible SecondaryEmail struct
14 | @objc
15 | public class DBXSecondaryEmailsSecondaryEmail: NSObject {
16 | /// Secondary email address.
17 | @objc
18 | public var email: String { swift.email }
19 | /// Whether or not the secondary email address is verified to be owned by a user.
20 | @objc
21 | public var isVerified: NSNumber { swift.isVerified as NSNumber }
22 |
23 | @objc
24 | public init(email: String, isVerified: NSNumber) {
25 | self.swift = SecondaryEmails.SecondaryEmail(email: email, isVerified: isVerified.boolValue)
26 | }
27 |
28 | let swift: SecondaryEmails.SecondaryEmail
29 |
30 | public init(swift: SecondaryEmails.SecondaryEmail) {
31 | self.swift = swift
32 | }
33 |
34 | @objc
35 | public override var description: String { swift.description }
36 | }
37 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXSharingAppAuthRoutes.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible routes for the sharing namespace
11 | /// For Swift routes see SharingAppAuthRoutes
12 | @objc
13 | public class DBXSharingAppAuthRoutes: NSObject {
14 | private let swift: SharingAppAuthRoutes
15 | init(swift: SharingAppAuthRoutes) {
16 | self.swift = swift
17 | self.client = swift.client.objc
18 | }
19 |
20 | public let client: DBXDropboxTransportClient
21 |
22 | /// Get the shared link's metadata.
23 | ///
24 | /// - scope: sharing.read
25 | ///
26 | /// - parameter url: URL of the shared link.
27 | /// - parameter path: If the shared link is to a folder, this parameter can be used to retrieve the metadata for a
28 | /// specific file or sub-folder in this folder. A relative path should be used.
29 | /// - parameter linkPassword: If the shared link has a password, this parameter can be used.
30 | ///
31 | /// - returns: Through the response callback, the caller will receive a `Sharing.SharedLinkMetadata` object on
32 | /// success or a `Sharing.SharedLinkError` object on failure.
33 | @objc
34 | @discardableResult public func getSharedLinkMetadata(url: String, path: String?, linkPassword: String?) -> DBXSharingGetSharedLinkMetadataRpcRequest {
35 | let swift = swift.getSharedLinkMetadata(url: url, path: path, linkPassword: linkPassword)
36 | return DBXSharingGetSharedLinkMetadataRpcRequest(swift: swift)
37 | }
38 |
39 | /// Get the shared link's metadata.
40 | ///
41 | /// - scope: sharing.read
42 | ///
43 | /// - returns: Through the response callback, the caller will receive a `Sharing.SharedLinkMetadata` object on
44 | /// success or a `Sharing.SharedLinkError` object on failure.
45 | @objc
46 | @discardableResult public func getSharedLinkMetadata(url: String) -> DBXSharingGetSharedLinkMetadataRpcRequest {
47 | let swift = swift.getSharedLinkMetadata(url: url)
48 | return DBXSharingGetSharedLinkMetadataRpcRequest(swift: swift)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Generated/DBXUsersCommon.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 | /// Auto-generated by Stone, do not modify.
5 | ///
6 |
7 | import Foundation
8 | import SwiftyDropbox
9 |
10 | /// Objective-C compatible datatypes for the users_common namespace
11 | /// For Swift see users_common
12 |
13 | /// What type of account this user has.
14 | @objc
15 | public class DBXUsersCommonAccountType: NSObject {
16 | let swift: UsersCommon.AccountType
17 |
18 | public init(swift: UsersCommon.AccountType) {
19 | self.swift = swift
20 | }
21 |
22 | public static func factory(swift: UsersCommon.AccountType) -> DBXUsersCommonAccountType {
23 | switch swift {
24 | case .basic:
25 | return DBXUsersCommonAccountTypeBasic()
26 | case .pro:
27 | return DBXUsersCommonAccountTypePro()
28 | case .business:
29 | return DBXUsersCommonAccountTypeBusiness()
30 | }
31 | }
32 |
33 | @objc
34 | public override var description: String { swift.description }
35 |
36 | @objc
37 | public var asBasic: DBXUsersCommonAccountTypeBasic? {
38 | self as? DBXUsersCommonAccountTypeBasic
39 | }
40 |
41 | @objc
42 | public var asPro: DBXUsersCommonAccountTypePro? {
43 | self as? DBXUsersCommonAccountTypePro
44 | }
45 |
46 | @objc
47 | public var asBusiness: DBXUsersCommonAccountTypeBusiness? {
48 | self as? DBXUsersCommonAccountTypeBusiness
49 | }
50 | }
51 |
52 | /// The basic account type.
53 | @objc
54 | public class DBXUsersCommonAccountTypeBasic: DBXUsersCommonAccountType {
55 | @objc
56 | public init() {
57 | let swift = UsersCommon.AccountType.basic
58 | super.init(swift: swift)
59 | }
60 | }
61 |
62 | /// The Dropbox Pro account type.
63 | @objc
64 | public class DBXUsersCommonAccountTypePro: DBXUsersCommonAccountType {
65 | @objc
66 | public init() {
67 | let swift = UsersCommon.AccountType.pro
68 | super.init(swift: swift)
69 | }
70 | }
71 |
72 | /// The Dropbox Business account type.
73 | @objc
74 | public class DBXUsersCommonAccountTypeBusiness: DBXUsersCommonAccountType {
75 | @objc
76 | public init() {
77 | let swift = UsersCommon.AccountType.business
78 | super.init(swift: swift)
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/DBXCertificatePinning.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | @objc
9 | public protocol DBXAuthChallengeHandler {
10 | func handle(challenge: URLAuthenticationChallenge) -> DBXAuthChallengeHandlerResult
11 | }
12 |
13 | extension DBXAuthChallengeHandler {
14 | var swift: AuthChallenge.Handler {
15 | { [weak self] challenge in
16 | guard let self = self else {
17 | return (.cancelAuthenticationChallenge, nil)
18 | }
19 | let result = self.handle(challenge: challenge)
20 | return (result.disposition, result.credential)
21 | }
22 | }
23 | }
24 |
25 | public class DBXAuthChallengeHandlerResult: NSObject {
26 | @objc
27 | public let disposition: URLSession.AuthChallengeDisposition
28 | @objc
29 | public let credential: URLCredential?
30 |
31 | @objc
32 | init(disposition: URLSession.AuthChallengeDisposition, credential: URLCredential?) {
33 | self.disposition = disposition
34 | self.credential = credential
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/DBXDropboxAppClient.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | /// The client for the App API. Call routes using the namespaces inside this object (inherited from parent).
9 | @objc
10 | public class DBXDropboxAppClient: DBXDropboxAppBase {
11 | let subSwift: DropboxAppClient
12 |
13 | /// Initialize a client from swift using an existing Swift client.
14 | ///
15 | /// - Parameter swift: The underlying DropboxAppClient to make API calls.
16 | public init(swift: DropboxAppClient) {
17 | self.subSwift = swift
18 | super.init(swiftClient: swift.client)
19 | }
20 |
21 | /// Designated Initializer.
22 | ///
23 | /// - Parameter transportClient: The underlying DropboxTransportClient to make API calls.
24 | @objc
25 | public convenience init(transportClient: DBXDropboxTransportClient) {
26 | self.init(swift: DropboxAppClient(transportClient: transportClient.swift))
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/DBXDropboxTeamClient.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | /// The client for the Business API. Call routes using the namespaces inside this object (inherited from parent).
9 |
10 | extension DropboxTeamClient {
11 | var objc: DBXDropboxTeamClient {
12 | DBXDropboxTeamClient(swift: self)
13 | }
14 | }
15 |
16 | @objc
17 | public class DBXDropboxTeamClient: DBXDropboxTeamBase {
18 | let subSwift: DropboxTeamClient
19 |
20 | fileprivate init(swift: DropboxTeamClient) {
21 | self.subSwift = swift
22 | super.init(swiftClient: swift.client)
23 | }
24 |
25 | /// Initialize a client with a static accessToken string.
26 | /// Use this method if your access token is long-lived.
27 | ///
28 | /// - Parameters:
29 | /// - accessToken: Static access token string.
30 | /// - sessionConfiguration: Optional custom network session configuration
31 | ///
32 | @objc
33 | public convenience init(
34 | accessToken: String,
35 | sessionConfiguration: DBXNetworkSessionConfiguration? = nil
36 | ) {
37 | let transportClient = DBXDropboxTransportClient(accessToken: accessToken)
38 | self.init(transportClient: transportClient)
39 | }
40 |
41 | /// Initialize a client with an `AccessTokenProvider`.
42 | /// Use this method if your access token is short-lived.
43 | /// See `ShortLivedAccessTokenProvider` for a default implementation.
44 | ///
45 | /// - Parameter accessTokenProvider: Access token provider that wraps a short-lived token and its refresh logic.
46 | @objc
47 | public convenience init(
48 | accessTokenProvider: DBXAccessTokenProvider,
49 | sessionConfiguration: DBXNetworkSessionConfiguration? = nil
50 | ) {
51 | let transportClient = DBXDropboxTransportClient(accessTokenProvider: accessTokenProvider)
52 | self.init(transportClient: transportClient)
53 | }
54 |
55 | /// Initialize a client with an `DropboxAccessToken`.
56 | ///
57 | /// - Parameters:
58 | /// - accessToken: The token itself, could be long or short lived.
59 | /// - dropboxOauthManager: an oauthManager, used for creating the token provider.
60 | /// - sessionConfiguration: Optional custom network session configuration
61 | @objc
62 | public convenience init(
63 | accessToken: DBXDropboxAccessToken,
64 | dropboxOauthManager: DBXDropboxOAuthManager,
65 | sessionConfiguration: DBXNetworkSessionConfiguration? = nil
66 | ) {
67 | let accessTokenProvider = dropboxOauthManager.accessTokenProviderForToken(accessToken)
68 | let transportClient = DBXDropboxTransportClient(accessTokenProvider: accessTokenProvider)
69 | self.init(transportClient: transportClient)
70 | }
71 |
72 | /// Designated Initializer.
73 | ///
74 | /// - Parameter transportClient: The underlying DropboxTransportClient to make API calls.
75 | @objc
76 | public convenience init(transportClient: DBXDropboxTransportClient) {
77 | self.init(swift: DropboxTeamClient(transportClient: transportClient.swift))
78 | }
79 |
80 | /// Creates a new DropboxClient instance for the team member id.
81 | ///
82 | /// - Parameter memberId: Team member id.
83 | /// - Returns: A new DropboxClient instance that can be used to call APIs on the team member's behalf.
84 | @objc
85 | public func asMember(_ memberId: String) -> DBXDropboxClient {
86 | DropboxClient(accessTokenProvider: subSwift.accessTokenProvider, selectUser: memberId).objc
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/DBXReconnectionHelpers.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | extension ReconnectionError {
9 | var objc: DBXReconnectionHelperError {
10 | DBXReconnectionHelperError(swift: self)
11 | }
12 | }
13 |
14 | @objc
15 | public class DBXReconnectionHelperError: NSObject {
16 | let swift: ReconnectionError
17 |
18 | @objc
19 | public var errorMessage: String { swift.reconnectionErrorKind.rawValue }
20 |
21 | @objc
22 | public var taskDescription: String? { swift.taskDescription }
23 |
24 | init(swift: ReconnectionError) {
25 | self.swift = swift
26 | }
27 | }
28 |
29 | @objc
30 | public class DBXReconnectionResult: NSObject {
31 | @objc
32 | public let request: DBXRequest?
33 | @objc
34 | public let error: DBXReconnectionHelperError?
35 |
36 | init(request: DBXRequest?, error: DBXReconnectionHelperError?) {
37 | self.request = request
38 | self.error = error
39 | }
40 | }
41 |
42 | @objc
43 | public class DBXDefaultBackgroundExtensionSessionCreationInfo: NSObject {
44 | let swift: DefaultBackgroundExtensionSessionCreationInfo
45 |
46 | public init(swift: DefaultBackgroundExtensionSessionCreationInfo) {
47 | self.swift = swift
48 | }
49 |
50 | @objc
51 | public init(backgroundSessionIdentifier: String, sharedContainerIdentifier: String) {
52 | self.swift = DefaultBackgroundExtensionSessionCreationInfo(
53 | backgroundSessionIdentifier: backgroundSessionIdentifier,
54 | sharedContainerIdentifier: sharedContainerIdentifier
55 | )
56 | }
57 | }
58 |
59 | @objc
60 | public class DBXCustomBackgroundExtensionSessionCreationInfo: NSObject {
61 | let swift: CustomBackgroundExtensionSessionCreationInfo
62 |
63 | @objc
64 | public init(backgroundTransportClient: DBXDropboxTransportClient) {
65 | self.swift = .init(backgroundTransportClient: backgroundTransportClient.swift)
66 | }
67 |
68 | @objc
69 | public init(backgroundSessionConfiguration: DBXNetworkSessionConfiguration) {
70 | self.swift = .init(backgroundSessionConfiguration: backgroundSessionConfiguration.swift)
71 | }
72 |
73 | init(swift: CustomBackgroundExtensionSessionCreationInfo) {
74 | self.swift = swift
75 | }
76 | }
77 |
78 | @objc
79 | public class DBXBackgroundExtensionSessionCreationInfo: NSObject {
80 | let swift: BackgroundExtensionSessionCreationInfo
81 |
82 | @objc
83 | public init(defaultInfo: DBXDefaultBackgroundExtensionSessionCreationInfo) {
84 | self.swift = .init(defaultInfo: defaultInfo.swift)
85 | }
86 |
87 | @objc
88 | public init(customInfo: DBXCustomBackgroundExtensionSessionCreationInfo) {
89 | self.swift = .init(customInfo: customInfo.swift)
90 | }
91 |
92 | init(swift: BackgroundExtensionSessionCreationInfo) {
93 | self.swift = swift
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/DBXRequest.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | @objc
8 | public protocol DBXRequest {
9 | var clientPersistedString: String? { get }
10 |
11 | @available(iOS 13.0, macOS 10.13, *)
12 | var earliestBeginDate: Date? { get }
13 |
14 | @discardableResult
15 | func persistingString(string: String?) -> Self
16 |
17 | @available(iOS 13.0, macOS 10.13, *)
18 | @discardableResult
19 | func settingEarliestBeginDate(date: Date?) -> Self
20 |
21 | func cancel()
22 | }
23 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/NetworkSession/DBXNetworkSessionConfiguration.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | extension NetworkSessionConfiguration {
9 | var objc: DBXNetworkSessionConfiguration {
10 | DBXNetworkSessionConfiguration(swift: self)
11 | }
12 | }
13 |
14 | public class DBXNetworkSessionConfiguration: NSObject {
15 | var swift: NetworkSessionConfiguration
16 |
17 | fileprivate init(swift: NetworkSessionConfiguration) {
18 | self.swift = swift
19 | }
20 |
21 | @objc
22 | public var timeoutIntervalForRequest: Double {
23 | get {
24 | swift.timeoutIntervalForRequest
25 | }
26 | set {
27 | swift.timeoutIntervalForRequest = newValue
28 | }
29 | }
30 |
31 | @objc
32 | public var timeoutIntervalForResource: Double {
33 | get {
34 | swift.timeoutIntervalForResource
35 | }
36 | set {
37 | swift.timeoutIntervalForResource = newValue
38 | }
39 | }
40 |
41 | @objc
42 | public var allowsCellularAccess: Bool {
43 | get {
44 | swift.allowsCellularAccess
45 | }
46 | set {
47 | swift.allowsCellularAccess = newValue
48 | }
49 | }
50 |
51 | @objc
52 | @available(iOS 13.0, macOS 10.15, *)
53 | public var allowsExpensiveNetworkAccess: Bool {
54 | get {
55 | swift.allowsExpensiveNetworkAccess
56 | }
57 | set {
58 | swift.allowsExpensiveNetworkAccess = newValue
59 | }
60 | }
61 |
62 | @objc
63 | @available(iOS 13.0, macOS 10.15, *)
64 | public var allowsConstrainedNetworkAccess: Bool {
65 | get {
66 | swift.allowsConstrainedNetworkAccess
67 | }
68 | set {
69 | swift.allowsConstrainedNetworkAccess = newValue
70 | }
71 | }
72 |
73 | @objc
74 | public var sharedContainerIdentifier: String? {
75 | get {
76 | swift.sharedContainerIdentifier
77 | }
78 | set {
79 | swift.sharedContainerIdentifier = newValue
80 | }
81 | }
82 |
83 | @objc
84 | public var httpMaximumConnectionsPerHost: Int {
85 | get {
86 | swift.httpMaximumConnectionsPerHost
87 | }
88 | set {
89 | swift.httpMaximumConnectionsPerHost = newValue
90 | }
91 | }
92 |
93 | @objc
94 | public static var `default` = DBXNetworkSessionConfiguration(swift: NetworkSessionConfiguration.default)
95 | @objc
96 | public static var defaultLongpoll = DBXNetworkSessionConfiguration(swift: NetworkSessionConfiguration.defaultLongpoll)
97 | @objc
98 | public static func background(withIdentifier identifier: String) -> DBXNetworkSessionConfiguration {
99 | DBXNetworkSessionConfiguration(swift: NetworkSessionConfiguration(kind: .background(identifier)))
100 | }
101 |
102 | @objc
103 | public static func background(withIdentifier identifier: String, sharedContainerIdentifier: String) -> DBXNetworkSessionConfiguration {
104 | DBXNetworkSessionConfiguration(
105 | swift: NetworkSessionConfiguration
106 | .background(withIdentifier: identifier, sharedContainerIdentifier: sharedContainerIdentifier)
107 | )
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/OAuth/DBXAccessTokenProvider.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | extension AccessTokenProvider {
9 | var objc: DBXAccessTokenProvider {
10 | DBXAccessTokenProvider(swift: self)
11 | }
12 | }
13 |
14 | @objc
15 | public class DBXAccessTokenProvider: NSObject {
16 | @objc
17 | public var accessToken: String { swift.accessToken }
18 |
19 | let swift: AccessTokenProvider
20 |
21 | fileprivate init(swift: AccessTokenProvider) {
22 | self.swift = swift
23 | }
24 | }
25 |
26 | extension DBXAccessTokenProvider: AccessTokenProvider {
27 | public func refreshAccessTokenIfNecessary(completion: @escaping DropboxOAuthCompletion) {
28 | swift.refreshAccessTokenIfNecessary(completion: completion)
29 | }
30 | }
31 |
32 | extension LongLivedAccessTokenProvider {
33 | var objc: DBXLongLivedAccessTokenProvider {
34 | DBXLongLivedAccessTokenProvider(swift: self)
35 | }
36 | }
37 |
38 | public class DBXLongLivedAccessTokenProvider: DBXAccessTokenProvider {
39 | fileprivate init(swift: LongLivedAccessTokenProvider) {
40 | super.init(swift: swift)
41 | }
42 |
43 | @objc
44 | public init(accessToken: String) {
45 | super.init(swift: LongLivedAccessTokenProvider(accessToken: accessToken))
46 | }
47 | }
48 |
49 | extension ShortLivedAccessTokenProvider {
50 | var objc: DBXShortLivedAccessTokenProvider {
51 | DBXShortLivedAccessTokenProvider(swift: self)
52 | }
53 | }
54 |
55 | @objc
56 | public class DBXShortLivedAccessTokenProvider: DBXAccessTokenProvider {
57 | fileprivate init(swift: ShortLivedAccessTokenProvider) {
58 | super.init(swift: swift)
59 | }
60 |
61 | /// - Parameters:
62 | /// - token: The `DropboxAccessToken` object for a short-lived token.
63 | /// - tokenRefresher: Helper object that refreshes a token over network.
64 | @objc
65 | init(token: DBXDropboxAccessToken, tokenRefresher: DBXAccessTokenRefreshing) {
66 | super.init(swift: ShortLivedAccessTokenProvider(token: token.swift, tokenRefresher: tokenRefresher.swift))
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/OAuth/DBXAuthSession.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | extension ScopeRequest {
9 | var objc: DBXScopeRequest {
10 | DBXScopeRequest(swift: self)
11 | }
12 | }
13 |
14 | @objc
15 | public class DBXScopeRequest: NSObject {
16 | let swift: ScopeRequest
17 |
18 | /// Type of the requested scopes.
19 | @objc public enum DBXScopeType: Int {
20 | case team
21 | case user
22 | }
23 |
24 | /// An array of scopes to be granted.
25 | @objc
26 | var scopes: [String] { swift.scopes }
27 | /// Boolean indicating whether to keep all previously granted scopes.
28 | @objc
29 | var includeGrantedScopes: Bool { swift.includeGrantedScopes }
30 | /// Type of the scopes to be granted.
31 | @objc
32 | var scopeType: DBXScopeType {
33 | switch swift.scopeType {
34 | case .team:
35 | return .team
36 | case .user:
37 | return .user
38 | }
39 | }
40 |
41 | /// String representation of the scopes, used in URL query. Nil if the array is empty.
42 | @objc
43 | var scopeString: String? {
44 | swift.scopeString
45 | }
46 |
47 | /// Designated Initializer.
48 | ///
49 | /// - Parameters:
50 | /// - scopeType: Type of the requested scopes.
51 | /// - scopes: A list of scope returned by Dropbox server. Each scope correspond to a group of API endpoints.
52 | /// To call one API endpoint you have to obtains the scope first otherwise you will get HTTP 401.
53 | /// - includeGrantedScopes: If false, Dropbox will give you the scopes in scopes array.
54 | /// Otherwise Dropbox server will return a token with all scopes user previously granted your app
55 | /// together with the new scopes.
56 | @objc
57 | public init(scopeType: DBXScopeType, scopes: [String], includeGrantedScopes: Bool) {
58 | let swiftScopeType: ScopeRequest.ScopeType = scopeType == .team ? .team : .user
59 | self.swift = ScopeRequest(scopeType: swiftScopeType, scopes: scopes, includeGrantedScopes: includeGrantedScopes)
60 | }
61 |
62 | fileprivate init(swift: ScopeRequest) {
63 | self.swift = swift
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxObjC/Shared/Handwritten/OAuth/DBXSecureStorageAccess.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2022 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | @objc
9 | public protocol DBXSecureStorageAccess {
10 | func checkAccessibilityMigrationOneTime()
11 | func setAccessTokenData(for userId: String, data: Data) -> Bool
12 | func getAllUserIds() -> [String]
13 | func getDropboxAccessToken(for key: String) -> DBXDropboxAccessToken?
14 | func deleteInfo(for key: String) -> Bool
15 | func deleteInfoForAllKeys() -> Bool
16 | }
17 |
18 | extension SecureStorageAccessDefaultImpl {
19 | var objc: DBXSecureStorageAccessDefaultImpl {
20 | DBXSecureStorageAccessDefaultImpl(swift: self)
21 | }
22 | }
23 |
24 | @objc
25 | open class DBXSecureStorageAccessImpl: NSObject, DBXSecureStorageAccess {
26 | let swift: SecureStorageAccess
27 |
28 | public init(swift: SecureStorageAccess) {
29 | self.swift = swift
30 | }
31 |
32 | public func checkAccessibilityMigrationOneTime() {
33 | swift.checkAccessibilityMigrationOneTime()
34 | }
35 |
36 | public func setAccessTokenData(for userId: String, data: Data) -> Bool {
37 | swift.setAccessTokenData(for: userId, data: data)
38 | }
39 |
40 | public func getAllUserIds() -> [String] {
41 | swift.getAllUserIds()
42 | }
43 |
44 | public func getDropboxAccessToken(for key: String) -> DBXDropboxAccessToken? {
45 | swift.getDropboxAccessToken(for: key)?.objc
46 | }
47 |
48 | public func deleteInfo(for key: String) -> Bool {
49 | swift.deleteInfo(for: key)
50 | }
51 |
52 | public func deleteInfoForAllKeys() -> Bool {
53 | swift.deleteInfoForAllKeys()
54 | }
55 | }
56 |
57 | @objc
58 | public class DBXSecureStorageAccessDefaultImpl: DBXSecureStorageAccessImpl {
59 | @objc
60 | public convenience init() {
61 | self.init(swift: SecureStorageAccessDefaultImpl())
62 | }
63 |
64 | fileprivate init(swift: SecureStorageAccessDefaultImpl) {
65 | super.init(swift: swift)
66 | }
67 | }
68 |
69 | extension DBXSecureStorageAccess {
70 | var swift: SecureStorageAccess {
71 | SecureStorageAccessBridge(objc: self)
72 | }
73 | }
74 |
75 | public class SecureStorageAccessBridge: NSObject, SecureStorageAccess {
76 | let objc: DBXSecureStorageAccess
77 |
78 | init(objc: DBXSecureStorageAccess) {
79 | self.objc = objc
80 | }
81 |
82 | public func checkAccessibilityMigrationOneTime() {
83 | objc.checkAccessibilityMigrationOneTime()
84 | }
85 |
86 | public func setAccessTokenData(for userId: String, data: Data) -> Bool {
87 | objc.setAccessTokenData(for: userId, data: data)
88 | }
89 |
90 | public func getAllUserIds() -> [String] {
91 | objc.getAllUserIds()
92 | }
93 |
94 | public func getDropboxAccessToken(for key: String) -> DropboxAccessToken? {
95 | objc.getDropboxAccessToken(for: key)?.swift
96 | }
97 |
98 | public func deleteInfo(for key: String) -> Bool {
99 | objc.deleteInfo(for: key)
100 | }
101 |
102 | public func deleteInfoForAllKeys() -> Bool {
103 | objc.deleteInfoForAllKeys()
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxUnitTests/ReconnectionHelperPersistedRequestInfoTests.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | @testable import SwiftyDropbox
8 | import XCTest
9 |
10 | final class TestReconnectionHelperPersistedRequestInfo: XCTestCase {
11 | let routeName = "deleteV2"
12 | let routeNamespace = "files"
13 | let clientProvidedInfo = "example"
14 |
15 | let destination = URL(string: "/some/file.jpg")!
16 | let overwrite = true
17 |
18 | lazy var uploadInfo: ReconnectionHelpers.PersistedRequestInfo = .upload(
19 | ReconnectionHelpers.PersistedRequestInfo.StandardInfo(
20 | originalSDKVersion: DropboxClientsManager.sdkVersion,
21 | routeName: routeName,
22 | routeNamespace: routeNamespace,
23 | clientProvidedInfo: clientProvidedInfo
24 | )
25 | )
26 |
27 | lazy var downloadFileInfo: ReconnectionHelpers.PersistedRequestInfo = .downloadFile(
28 | ReconnectionHelpers.PersistedRequestInfo.DownloadFileInfo(
29 | originalSDKVersion: DropboxClientsManager.sdkVersion,
30 | routeName: routeName,
31 | routeNamespace: routeNamespace,
32 | clientProvidedInfo: clientProvidedInfo,
33 | destination: destination,
34 | overwrite: overwrite
35 | )
36 | )
37 |
38 | func testCodingRoundtrip() throws {
39 | XCTAssertEqual(
40 | uploadInfo,
41 | try ReconnectionHelpers.PersistedRequestInfo.from(jsonString: try uploadInfo.asJsonString())
42 | )
43 | }
44 |
45 | func testDownloadFileCodingRoundtrip() throws {
46 | XCTAssertEqual(
47 | downloadFileInfo,
48 | try ReconnectionHelpers.PersistedRequestInfo.from(jsonString: try downloadFileInfo.asJsonString())
49 | )
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxUnitTests/ReconnectionHelperRouteNameTests.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2024 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | @testable import SwiftyDropbox
8 | import XCTest
9 |
10 | final class TestReconnectionHelperRouteNameMatching: XCTestCase {
11 | private let destination = URL(string: "/some/file.jpg")!
12 |
13 | func testMatchingFilesUploadSessionAppendV2() throws {
14 | try executeMatchingTest(route: Files.uploadSessionAppendV2, expectedRebuiltDescription: "files/upload_session/append_v2", upload: true)
15 | }
16 |
17 | func testMatchingFilesDownloadZip() throws {
18 | try executeMatchingTest(route: Files.downloadZip, expectedRebuiltDescription: "files/download_zip", upload: false)
19 | }
20 |
21 | func testMatchingSharingGetSharedLinkFile() throws {
22 | try executeMatchingTest(route: Sharing.getSharedLinkFile, expectedRebuiltDescription: "sharing/get_shared_link_file", upload: false)
23 | }
24 |
25 | func testMatchingPaperDocsDownload() throws {
26 | try executeMatchingTest(route: Paper.docsDownload, expectedRebuiltDescription: "paper/docs/download", upload: false)
27 | }
28 |
29 | private func executeMatchingTest(route: Route, expectedRebuiltDescription: String, upload: Bool) throws {
30 | let persistedInfo: ReconnectionHelpers.PersistedRequestInfo = upload
31 | ? .upload(
32 | .init(
33 | originalSDKVersion: DropboxClientsManager.sdkVersion,
34 | routeName: route.name,
35 | routeNamespace: route.namespace,
36 | clientProvidedInfo: nil
37 | )
38 | )
39 | : .downloadFile(
40 | .init(
41 | originalSDKVersion: DropboxClientsManager.sdkVersion,
42 | routeName: route.name,
43 | routeNamespace: route.namespace,
44 | destination: destination,
45 | overwrite: true
46 | )
47 | )
48 |
49 | let request = MockApiRequest(identifier: 0)
50 | request.taskDescription = try persistedInfo.asJsonString()
51 |
52 | let rebuiltRequest = try ReconnectionHelpers.rebuildRequest(apiRequest: request, client: MockDropboxTransportClient())
53 |
54 | // Assert that request was successfully rebuilt
55 | XCTAssertEqual(rebuiltRequest.description, expectedRebuiltDescription)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxUnitTests/Request+Async.test.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2023 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | @testable import SwiftyDropbox
6 | import XCTest
7 |
8 | @available(iOS 13.0, macOS 10.15, *)
9 | final class RequestAsyncTests: XCTestCase {
10 | func testRpcResponseFails() async throws {
11 | let mockTransferClient = MockDropboxTransportClient()
12 | mockTransferClient.mockRequestHandler = MockDropboxTransportClient.alwaysFailMockRequestHandler
13 | let apiClient = DropboxClient(transportClient: mockTransferClient)
14 |
15 | let exp = expectation(description: "should fail")
16 | do {
17 | _ = try await apiClient.check.user().response()
18 | XCTFail("This should fail")
19 | } catch {
20 | exp.fulfill()
21 | }
22 | await fulfillment(of: [exp])
23 | }
24 |
25 | func testRpcResponseSucceeds() async throws {
26 | let mockTransferClient = MockDropboxTransportClient()
27 | mockTransferClient.mockRequestHandler = { request in
28 | try? request.handleMockInput(.success(json: [:]))
29 | }
30 | let apiClient = DropboxClient(transportClient: mockTransferClient)
31 |
32 | let userCheck = try await apiClient.check.user().response()
33 | XCTAssertNotNil(userCheck)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxUnitTests/TestAsciiEncoding.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2023 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | @testable import SwiftyDropbox
8 | import XCTest
9 |
10 | final class TestAsciiEncoding: XCTestCase {
11 | let stringsToEncodedStrings = [
12 | "héllø wörld": "h\\u00e9ll\\u00f8 w\\u00f6rld",
13 | "hello": "hello",
14 | "": "",
15 | "こんにちは": "\\u3053\\u3093\\u306b\\u3061\\u306f",
16 | "this has a clustered flag 🇺🇸": "this has a clustered flag \\ud83c\\uddfa\\ud83c\\uddf8",
17 | "this is a big emoji 👩👩👧👦": "this is a big emoji \\ud83d\\udc69\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc67\\u200d\\ud83d\\udc66",
18 | "🍺": "\\ud83c\\udf7a",
19 | "this\nhas some whitespace": "this\nhas some whitespace",
20 | ]
21 |
22 | func testEncodings() {
23 | for (key, value) in stringsToEncodedStrings {
24 | let lhs = Utilities.asciiEscape(key)
25 | let rhs = value
26 | XCTAssertEqual(lhs, rhs)
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxUnitTests/TestNetworkSessionManager+Background.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | @testable import SwiftyDropbox
6 | import XCTest
7 |
8 | extension TestNetworkSessionManager {
9 | func testRecievingADelegateCallbackForAnUnregisteredTaskWrapsAndRegistersIt() throws {
10 | let request = sut.apiRequestData(request: { .example() }, networkTaskTag: "delegate-task")
11 | let mockRequest = try XCTUnwrap(request as? MockApiRequest)
12 | wait(for: taskCreationExpectations, timeout: 1)
13 |
14 | let underlyingTask = try XCTUnwrap(mockNetworkSession.tasks["delegate-task"] as? NetworkDataTask)
15 |
16 | sut.networkSession(mockNetworkSession, dataTask: underlyingTask, didReceive: Data())
17 |
18 | XCTAssertEqual(sut.requestMap.getAllRequests().count, 1)
19 | XCTAssertEqual(sut.requestMap.getAllRequests().first?.identifier, mockRequest.identifier)
20 | }
21 |
22 | func testMultipleDelegateCallbacksDoNotLeadToMultipleRegistrations() throws {
23 | let request = sut.apiRequestData(request: { .example() }, networkTaskTag: "delegate-task")
24 | let mockRequest = try XCTUnwrap(request as? MockApiRequest)
25 | wait(for: taskCreationExpectations, timeout: 1)
26 |
27 | let underlyingTask = try XCTUnwrap(mockNetworkSession.tasks["delegate-task"] as? NetworkDataTask)
28 |
29 | // First
30 | sut.networkSession(mockNetworkSession, dataTask: underlyingTask, didReceive: Data())
31 |
32 | // Second
33 | sut.networkSession(mockNetworkSession, task: underlyingTask, didCompleteWithError: nil)
34 |
35 | XCTAssertEqual(createdRequestCount, 1)
36 | XCTAssertEqual(sut.requestMap.getAllRequests().count, 1)
37 | XCTAssertEqual(sut.requestMap.getAllRequests().first?.identifier, mockRequest.identifier)
38 | }
39 |
40 | func testGetAllTasksRewrapsOnlyNewTasksAndReturnsAllUnownedApiRequests() throws {
41 | let e = expectation(description: "completion called")
42 |
43 | // Set a network session id so that the manager knows it's a background session
44 | // In background sessions we treat incoming unknown URLSessionDelegate calls differently
45 | mockNetworkSession.identifier = "bg"
46 |
47 | let existingApiRequest = sut.apiRequestData(request: { .example() }, networkTaskTag: "delegate-task")
48 | (existingApiRequest as? MockApiRequest)?.identifier = 0
49 | wait(for: taskCreationExpectations, timeout: 1)
50 |
51 | XCTAssertEqual(createdRequestCount, 1)
52 |
53 | // Add a pending task via URLSessionDelegate
54 | let pendingViaDelegateTask = MockNetworkTaskDelegate(request: .example())
55 | pendingViaDelegateTask.taskIdentifier = 1
56 | sut.networkSession(sut.session, task: pendingViaDelegateTask, didSendBodyData: 0, totalBytesSent: 0, totalBytesExpectedToSend: 0)
57 |
58 | // add a pending task to be vended from URLSession.getAllTasks
59 | let pendingViaCompletionTask = MockNetworkTaskDelegate(request: .example())
60 | pendingViaCompletionTask.taskIdentifier = 2
61 |
62 | mockNetworkSession.tasksPendingReconnection = [pendingViaCompletionTask]
63 |
64 | sut.getAllTasks { requests in
65 | XCTAssertEqual(requests.count, 2)
66 | XCTAssertEqual(self.createdRequestCount, 3)
67 | XCTAssertEqual(requests.idSet, [1, 2])
68 | e.fulfill()
69 | }
70 |
71 | wait(for: [e], timeout: 1)
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Source/SwiftyDropboxUnitTests/TestSecureStorageAccess.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | @testable import SwiftyDropbox
6 | import XCTest
7 |
8 | final class TestSecureStorageAccess: XCTestCase {
9 | private var appBundlePath: String!
10 | private var extensionBundlePath: String!
11 | private var macAppBundlePath: String!
12 |
13 | override func setUpWithError() throws {
14 | appBundlePath = "/private/var/containers/Bundle/Application/some-uuid/TestSwiftyDropbox_iOS.app"
15 | extensionBundlePath = "/private/var/containers/Bundle/Application/some-uuid/TestSwiftyDropbox_iOS.app/PlugIns/TestSwiftyDropbox_ActionExtension.appex"
16 | macAppBundlePath = "/Users/name/Library/Developer/Xcode/DerivedData/TestSwiftyDropbox-uuid/Build/Products/Debug/TestSwiftyDropbox_macOS.app"
17 | }
18 |
19 | func testCanFindAppBundleFromExtension() {
20 | let bundlePath = SecureStorageAccessDefaultImpl.appBundleAbsolutePath(from: extensionBundlePath)
21 | XCTAssertEqual(bundlePath, appBundlePath)
22 | }
23 |
24 | func testCanFindAppBundleFromApp() {
25 | let bundlePath = SecureStorageAccessDefaultImpl.appBundleAbsolutePath(from: appBundlePath)
26 | XCTAssertEqual(bundlePath, appBundlePath)
27 | }
28 |
29 | func testPathIsAbsolute() {
30 | let bundlePath = SecureStorageAccessDefaultImpl.appBundleAbsolutePath(from: macAppBundlePath)
31 | XCTAssertEqual(bundlePath.first, "/")
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/SwiftyDropbox.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'SwiftyDropbox'
3 | s.version = '10.2.0'
4 | s.summary = 'Dropbox Swift SDK for API v2'
5 | s.homepage = 'https://dropbox.com/developers/'
6 | s.license = 'MIT'
7 | s.author = { 'Stephen Cobbe' => 'scobbe@dropbox.com' }
8 | s.source = { :git => 'https://github.com/dropbox/SwiftyDropbox.git', :tag => s.version }
9 |
10 | s.source_files = 'Source/SwiftyDropbox/Shared/**/*.{swift,h,m}'
11 | s.osx.source_files = 'Source/SwiftyDropbox/Platform/SwiftyDropbox_macOS/**/*.{swift,h,m}'
12 | s.ios.source_files = 'Source/SwiftyDropbox/Platform/SwiftyDropbox_iOS/**/*.{swift,h,m}'
13 |
14 | s.resource_bundles = {
15 | 'SwiftyDropboxPrivacyInfo' => ['Source/SwiftyDropbox/PrivacyInfo.xcprivacy'],
16 | }
17 |
18 | s.requires_arc = true
19 | s.swift_version = '5.6'
20 |
21 | s.osx.deployment_target = '10.13'
22 | s.ios.deployment_target = '12.0'
23 |
24 | s.osx.frameworks = 'AppKit', 'WebKit', 'SystemConfiguration', 'Foundation'
25 | s.ios.frameworks = 'UIKit', 'WebKit', 'SystemConfiguration', 'Foundation'
26 | end
27 |
--------------------------------------------------------------------------------
/SwiftyDropboxObjc.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'SwiftyDropboxObjC'
3 | s.version = '10.2.0'
4 | s.summary = 'Objective-C Wrapper for Dropbox Swift SDK for API v2'
5 | s.homepage = 'https://dropbox.com/developers/'
6 | s.license = 'MIT'
7 | s.author = { 'Stephen Cobbe' => 'scobbe@dropbox.com' }
8 | s.source = { :git => 'https://github.com/dropbox/SwiftyDropbox.git', :tag => s.version }
9 |
10 | s.source_files = 'Source/SwiftyDropboxObjC/Shared/**/*.{swift,h,m}'
11 | s.osx.source_files = 'Source/SwiftyDropboxObjC/Platform/SwiftyDropbox_macOS/**/*.{swift,h,m}'
12 | s.ios.source_files = 'Source/SwiftyDropboxObjC/Platform/SwiftyDropbox_iOS/**/*.{swift,h,m}'
13 |
14 | s.resource_bundles = {
15 | 'SwiftyDropboxObjCPrivacyInfo' => ['Source/SwiftyDropboxObjC/PrivacyInfo.xcprivacy'],
16 | }
17 |
18 | s.requires_arc = true
19 | s.swift_version = '5.6'
20 |
21 | s.osx.deployment_target = '10.13'
22 | s.ios.deployment_target = '12.0'
23 |
24 | s.osx.frameworks = 'AppKit', 'WebKit', 'SystemConfiguration', 'Foundation'
25 | s.ios.frameworks = 'UIKit', 'WebKit', 'SystemConfiguration', 'Foundation'
26 |
27 | s.dependency 'SwiftyDropbox', '~> 10.2.0'
28 | end
29 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/IntegrationTests/BackgroundSessionTestClasses.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | enum BackgroundTestLogger {
9 | static var cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
10 | static var logsFileURL = cachesDirectory.appendingPathComponent("app_logs.txt")
11 |
12 | static func log(_ message: String) {
13 | NSLog(message)
14 | appendToFile(fileURL: logsFileURL, content: message)
15 | }
16 |
17 | static func appendToFile(fileURL: URL, content c: String) {
18 | let content = c + "\n"
19 | do {
20 | if FileManager.default.fileExists(atPath: fileURL.path) {
21 | let fileHandle = try FileHandle(forWritingTo: fileURL)
22 | fileHandle.seekToEndOfFile()
23 | if let data = content.data(using: .utf8) {
24 | fileHandle.write(data)
25 | }
26 | fileHandle.closeFile()
27 | } else {
28 | try content.write(to: fileURL, atomically: true, encoding: .utf8)
29 | }
30 | } catch {
31 | print("Error: Unable to append content to the file. \(error.localizedDescription)")
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/IntegrationTests/ObjC/ObjCTestData.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | @objc
8 | open class DBXTestData: NSObject {
9 | @objc static var testId: String { get { TestData.testId } set { TestData.testId = newValue } }
10 | @objc static var baseFolder: String { get { TestData.baseFolder } set { TestData.baseFolder = newValue } }
11 |
12 | @objc static var testFolderName: String { get { TestData.testFolderName } set { TestData.testFolderName = newValue } }
13 | @objc static var testFolderPath: String { get { TestData.testFolderPath } set { TestData.testFolderPath = newValue } }
14 |
15 | @objc static var testShareFolderName: String { get { TestData.testShareFolderName } set { TestData.testShareFolderName = newValue } }
16 | @objc static var testShareFolderPath: String { get { TestData.testShareFolderPath } set { TestData.testShareFolderPath = newValue } }
17 |
18 | @objc static var testFileName: String { get { TestData.testFileName } set { TestData.testFileName = newValue } }
19 | @objc static var testFilePath: String { get { TestData.testFilePath } set { TestData.testFilePath = newValue } }
20 |
21 | @objc static var testData: String { get { TestData.testData } set { TestData.testData = newValue } }
22 |
23 | @objc static var fileData: Data { get { TestData.fileData } set { TestData.fileData = newValue } }
24 | @objc static var fileManager: FileManager { get { TestData.fileManager } set { TestData.fileManager = newValue } }
25 | @objc static var directoryURL: URL { get { TestData.directoryURL } set { TestData.directoryURL = newValue } }
26 | @objc static var destURL: URL { get { TestData.destURL } set { TestData.destURL = newValue } }
27 |
28 | @objc static var accountId: String { get { TestData.accountId } set { TestData.accountId = newValue } }
29 | @objc static var accountId2: String { get { TestData.accountId2 } set { TestData.accountId2 = newValue } }
30 | @objc static var accountId3: String { get { TestData.accountId3 } set { TestData.accountId3 = newValue } }
31 | @objc static var accountId3Email: String { get { TestData.accountId3Email } set { TestData.accountId3Email = newValue } }
32 |
33 | @objc static var testIdTeam: String { get { TestData.testIdTeam } set { TestData.testIdTeam = newValue } }
34 | @objc static var groupName: String { get { TestData.groupName } set { TestData.groupName = newValue } }
35 | @objc static var groupExternalId: String { get { TestData.groupExternalId } set { TestData.groupExternalId = newValue } }
36 | @objc static var groupExternalIdDashObjc: String { TestData.groupExternalId + "-objc" }
37 |
38 | @objc static var teamMemberEmail: String { get { TestData.teamMemberEmail } set { TestData.teamMemberEmail = newValue } }
39 | @objc static var newMemberEmail: String { get { TestData.newMemberEmail } set { TestData.newMemberEmail = newValue } }
40 |
41 | @objc static var fullDropboxAppKey: String { get { TestData.fullDropboxAppKey } set { TestData.fullDropboxAppKey = newValue } }
42 | @objc static var fullDropboxAppSecret: String { get { TestData.fullDropboxAppSecret } set { TestData.fullDropboxAppSecret = newValue } }
43 | }
44 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/IntegrationTests/TestAppType.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | public enum AppPermission {
8 | case fullDropboxScoped
9 | case fullDropboxScopedForTeamTesting
10 | }
11 |
12 | let appPermission = AppPermission.fullDropboxScoped
13 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/IntegrationTests/TestData.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | open class TestData {
9 | // to avoid name collisions in the event of leftover test state from failure
10 | static var testId = String(arc4random_uniform(1_000))
11 |
12 | static var baseFolder = "/Testing/SwiftyDropboxTests"
13 |
14 | static var testFolderName = "testFolder"
15 | static var testFolderPath = baseFolder + "/" + testFolderName + "_" + testId
16 |
17 | static var testShareFolderName = "testShareFolder"
18 | static var testShareFolderPath = baseFolder + "/" + testShareFolderName + "_" + testId
19 |
20 | static var testFileName = "testFile"
21 | static var testFilePath = testFolderPath + "/" + testFileName
22 |
23 | static var testData = "testing data example"
24 |
25 | static var fileData = testData.data(using: String.Encoding.utf8, allowLossyConversion: false)!
26 | static var fileManager = FileManager.default
27 | static var directoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
28 | static var destURL = directoryURL.appendingPathComponent(testFileName)
29 |
30 | static var destURLException = directoryURL.appendingPathComponent(testFileName + "_does_not_exist")
31 |
32 | // user-specific information
33 |
34 | // account ID of the user you OAuth linked with in order to test
35 | static var accountId = ""
36 | // any additional valid Dropbox account ID
37 | static var accountId2 = ""
38 | // any additional valid Dropbox account ID
39 | static var accountId3 = ""
40 | // the email address of the account whose account ID is `accoundId3`
41 | static var accountId3Email = ""
42 |
43 | // team-specific data
44 |
45 | // to avoid name collisions in the event of leftover test state from failure
46 | static var testIdTeam = String(arc4random_uniform(1_000))
47 |
48 | static var groupName = "GroupName" + testIdTeam
49 | static var groupExternalId = "group-" + testIdTeam
50 |
51 | // user-specific information
52 |
53 | // email address of the team user you OAuth link with in order to test
54 | static var teamMemberEmail = ""
55 | static var newMemberEmail = ""
56 |
57 | // App key and secret
58 | static var fullDropboxAppKey = ""
59 | static var fullDropboxAppSecret = ""
60 |
61 | public static let backgroundSessionIdentifier = ""
62 | public static let extensionBackgroundSessionIdentifier = ""
63 | public static let sharedContainerIdentifier = ""
64 | }
65 |
66 | open class TestTeamData {}
67 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 | ///
3 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
4 | ///
5 |
6 | // This only exists so that Xcode doesn't display TestSwiftyDropbox
7 |
8 | import PackageDescription
9 |
10 | let package = Package(
11 | name: "client",
12 | products: [],
13 | targets: []
14 | )
15 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 |
3 | def shared_iOS_pods
4 | platform :ios, '12.0'
5 | pod 'SwiftyDropbox', :path => '../'
6 | pod 'SwiftyDropboxObjC', :path => '../'
7 | end
8 |
9 | def shared_macOS_pods
10 | platform :osx, '10.13'
11 | pod 'SwiftyDropbox', :path => '../'
12 | pod 'SwiftyDropboxObjC', :path => '../'
13 | end
14 |
15 | target "TestSwiftyDropbox_iOS" do
16 | shared_iOS_pods
17 |
18 | target 'TestSwiftyDropbox_ActionExtension' do
19 | inherit! :search_paths
20 | end
21 | end
22 |
23 | target "TestSwiftyDropbox_iOSTests" do
24 | shared_iOS_pods
25 | end
26 |
27 | target "TestSwiftyDropbox_macOS" do
28 | shared_macOS_pods
29 | end
30 |
31 | target "TestSwiftyDropbox_macOSTests" do
32 | shared_macOS_pods
33 | end
34 |
35 | target "TestSwiftyDropbox_SwiftUI (iOS)" do
36 | shared_iOS_pods
37 | end
38 |
39 | target "TestSwiftyDropbox_SwiftUI (macOS)" do
40 | shared_macOS_pods
41 | end
42 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - SwiftyDropbox (10.1.0)
3 | - SwiftyDropboxObjC (10.1.0):
4 | - SwiftyDropbox (~> 10.1.0)
5 |
6 | DEPENDENCIES:
7 | - SwiftyDropbox (from `../`)
8 | - SwiftyDropboxObjC (from `../`)
9 |
10 | EXTERNAL SOURCES:
11 | SwiftyDropbox:
12 | :path: "../"
13 | SwiftyDropboxObjC:
14 | :path: "../"
15 |
16 | SPEC CHECKSUMS:
17 | SwiftyDropbox: a023f55cb1bd8a81bb48c33eea529cd71faf8e29
18 | SwiftyDropboxObjC: c7f2189b65386016ea29942d222863dcd03159ac
19 |
20 | PODFILE CHECKSUM: e0f6bd11b29f3d698a8cf15c435947aa1ac4eee1
21 |
22 | COCOAPODS: 1.16.2
23 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_ActionExtension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSExtension
6 |
7 | NSExtensionAttributes
8 |
9 | NSExtensionActivationRule
10 |
11 | NSExtensionActivationSupportsWebURLWithMaxCount
12 | 1
13 |
14 | NSExtensionServiceAllowsFinderPreviewItem
15 |
16 | NSExtensionServiceAllowsTouchBarItem
17 |
18 | NSExtensionServiceFinderPreviewIconName
19 | NSActionTemplate
20 | NSExtensionServiceTouchBarBezelColorName
21 | TouchBarBezel
22 | NSExtensionServiceTouchBarIconName
23 | NSActionTemplate
24 |
25 | NSExtensionPointIdentifier
26 | com.apple.services
27 | NSExtensionPrincipalClass
28 | $(PRODUCT_MODULE_NAME).ActionRequestHandler
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_ActionExtension/TestSwiftyDropbox_ActionExtension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)group.com.getdropbox.TestSwiftyDropbox
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/Shared/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | },
93 | {
94 | "idiom" : "mac",
95 | "scale" : "1x",
96 | "size" : "16x16"
97 | },
98 | {
99 | "idiom" : "mac",
100 | "scale" : "2x",
101 | "size" : "16x16"
102 | },
103 | {
104 | "idiom" : "mac",
105 | "scale" : "1x",
106 | "size" : "32x32"
107 | },
108 | {
109 | "idiom" : "mac",
110 | "scale" : "2x",
111 | "size" : "32x32"
112 | },
113 | {
114 | "idiom" : "mac",
115 | "scale" : "1x",
116 | "size" : "128x128"
117 | },
118 | {
119 | "idiom" : "mac",
120 | "scale" : "2x",
121 | "size" : "128x128"
122 | },
123 | {
124 | "idiom" : "mac",
125 | "scale" : "1x",
126 | "size" : "256x256"
127 | },
128 | {
129 | "idiom" : "mac",
130 | "scale" : "2x",
131 | "size" : "256x256"
132 | },
133 | {
134 | "idiom" : "mac",
135 | "scale" : "1x",
136 | "size" : "512x512"
137 | },
138 | {
139 | "idiom" : "mac",
140 | "scale" : "2x",
141 | "size" : "512x512"
142 | }
143 | ],
144 | "info" : {
145 | "author" : "xcode",
146 | "version" : 1
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/Shared/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/iOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | class AppDelegate: UIResponder, UIApplicationDelegate, ObservableObject {
9 | var window: UIWindow?
10 |
11 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
12 | let processInfo = ProcessInfo.processInfo.environment
13 | let inTestScheme = processInfo["FULL_DROPBOX_API_APP_KEY"] != nil
14 |
15 | // Skip setup if launching for unit tests, XCTests set up the clients themselves
16 | if inTestScheme {
17 | return true
18 | }
19 |
20 | if TestData.fullDropboxAppKey.range(of: "<") != nil {
21 | print("\n\n\nMust set test data (in TestData.swift) before launching app.\n\n\nTerminating.....\n\n")
22 | exit(0)
23 | }
24 | switch appPermission {
25 | case .fullDropboxScoped:
26 | DropboxClientsManager.setupWithAppKey(TestData.fullDropboxAppKey)
27 | case .fullDropboxScopedForTeamTesting:
28 | DropboxClientsManager.setupWithTeamAppKey(TestData.fullDropboxAppKey)
29 | }
30 |
31 | return true
32 | }
33 |
34 | func application(
35 | _ application: UIApplication,
36 | configurationForConnecting connectingSceneSession: UISceneSession,
37 | options: UIScene.ConnectionOptions
38 | ) -> UISceneConfiguration {
39 | let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
40 | sceneConfig.delegateClass = SceneDelegate.self
41 | return sceneConfig
42 | }
43 | }
44 |
45 | class SceneDelegate: NSObject, UIWindowSceneDelegate, ObservableObject {
46 | @Published var userAuthed: Bool = false
47 |
48 | func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
49 | guard let url = URLContexts.first?.url else { return }
50 | let oauthCompletion: DropboxOAuthCompletion = { [weak self] in
51 | if let authResult = $0 {
52 | switch authResult {
53 | case .success:
54 | print("Success! User is logged into DropboxClientsManager.")
55 | self?.userAuthed = true
56 | case .cancel:
57 | print("Authorization flow was manually canceled by user!")
58 | self?.userAuthed = false
59 | case .error(_, let description):
60 | print("Error: \(String(describing: description))")
61 | self?.userAuthed = false
62 | }
63 | }
64 | }
65 |
66 | switch appPermission {
67 | case .fullDropboxScoped:
68 | _ = DropboxClientsManager.handleRedirectURL(url, completion: oauthCompletion)
69 | case .fullDropboxScopedForTeamTesting:
70 | _ = DropboxClientsManager.handleRedirectURLTeam(url, completion: oauthCompletion)
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/iOS/ContentView.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import SwiftUI
6 | import SwiftyDropbox
7 |
8 | struct ContentView: View {
9 | @EnvironmentObject private var appDelegate: AppDelegate
10 | @EnvironmentObject var sceneDelegate: SceneDelegate
11 | @ObservedObject var viewModel = ViewModel()
12 |
13 | var body: some View {
14 | if viewModel.isLinked || sceneDelegate.userAuthed {
15 | VStack {
16 | Button("Run API Tests", action: runApiTests)
17 | .padding()
18 | Button("Unlink Dropbox Account", action: unlink)
19 | .padding()
20 | }
21 | .padding()
22 | } else {
23 | Button("Link Dropbox (pkce code flow)", action: link)
24 | .padding()
25 | }
26 | }
27 |
28 | func runApiTests() {
29 | let unlink = {
30 | DropboxClientsManager.unlinkClients()
31 | viewModel.checkIsLinked()
32 | sceneDelegate.userAuthed = false
33 | exit(0)
34 | }
35 |
36 | switch appPermission {
37 | case .fullDropboxScoped:
38 | DropboxTester().testAllUserEndpoints(asMember: false, nextTest: unlink)
39 | case .fullDropboxScopedForTeamTesting:
40 | DropboxTeamTester().testTeamMemberFileAcessActions(unlink)
41 | }
42 | }
43 |
44 | func unlink() {
45 | DropboxClientsManager.unlinkClients()
46 | viewModel.checkIsLinked()
47 | sceneDelegate.userAuthed = false
48 | }
49 |
50 | func link() {
51 | let scopeRequest: ScopeRequest
52 | // note if you add new scopes, you need to relogin to update your token
53 | switch appPermission {
54 | case .fullDropboxScoped:
55 | scopeRequest = ScopeRequest(scopeType: .user, scopes: DropboxTester.scopes, includeGrantedScopes: false)
56 | case .fullDropboxScopedForTeamTesting:
57 | scopeRequest = ScopeRequest(scopeType: .team, scopes: DropboxTeamTester.scopes, includeGrantedScopes: false)
58 | }
59 | DropboxClientsManager.authorizeFromControllerV2(
60 | UIApplication.shared,
61 | controller: nil,
62 | loadingStatusDelegate: nil,
63 | openURL: { (url: URL) -> Void in UIApplication.shared.open(url, options: [:], completionHandler: nil) },
64 | scopeRequest: scopeRequest
65 | )
66 | }
67 | }
68 |
69 | class ViewModel: ObservableObject {
70 | @Published var isLinked: Bool
71 |
72 | init() {
73 | self.isLinked = ViewModel.sdkIsLinked()
74 | }
75 |
76 | func checkIsLinked() {
77 | isLinked = ViewModel.sdkIsLinked()
78 | }
79 |
80 | private static func sdkIsLinked() -> Bool {
81 | DropboxClientsManager.authorizedClient != nil || DropboxClientsManager.authorizedTeamClient != nil
82 | }
83 | }
84 |
85 | struct ContentView_Previews: PreviewProvider {
86 | static var previews: some View {
87 | ContentView()
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleURLTypes
6 |
7 |
8 | CFBundleTypeRole
9 | Editor
10 | CFBundleURLSchemes
11 |
12 | db-<APP_KEY>
13 | db-<APP_KEY>
14 | db-<APP_KEY>
15 |
16 |
17 |
18 | LSApplicationQueriesSchemes
19 |
20 | dbapi-2
21 | dbapi-8-emm
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/iOS/TestSwiftyDropboxApp.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import SwiftUI
6 |
7 | @main
8 | struct TestSwiftyDropboxApp: App {
9 | @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
10 |
11 | var body: some Scene {
12 | WindowGroup {
13 | ContentView()
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/macOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 | import SwiftyDropbox
7 |
8 | class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
9 | @Published var userAuthed: Bool = false
10 |
11 | func applicationDidFinishLaunching(_ aNotification: Notification) {
12 | let processInfo = ProcessInfo.processInfo.environment
13 | let inTestScheme = processInfo["FULL_DROPBOX_API_APP_KEY"] != nil
14 |
15 | // Skip setup if launching for unit tests, XCTests set up the clients themselves
16 | if inTestScheme {
17 | return
18 | }
19 |
20 | if TestData.fullDropboxAppKey.range(of: "<") != nil {
21 | print("\n\n\nMust set test data (in TestData.swift) before launching app.\n\n\nTerminating.....\n\n")
22 | exit(0)
23 | }
24 | switch appPermission {
25 | case .fullDropboxScoped:
26 | DropboxClientsManager.setupWithAppKeyDesktop(TestData.fullDropboxAppKey)
27 | case .fullDropboxScopedForTeamTesting:
28 | DropboxClientsManager.setupWithTeamAppKeyDesktop(TestData.fullDropboxAppKey)
29 | }
30 | NSAppleEventManager.shared()
31 | .setEventHandler(
32 | self,
33 | andSelector: #selector(handleGetURLEvent),
34 | forEventClass: AEEventClass(kInternetEventClass),
35 | andEventID: AEEventID(kAEGetURL)
36 | )
37 | }
38 |
39 | @objc func handleGetURLEvent(_ event: NSAppleEventDescriptor?, replyEvent: NSAppleEventDescriptor?) {
40 | if let aeEventDescriptor = event?.paramDescriptor(forKeyword: AEKeyword(keyDirectObject)) {
41 | if let urlStr = aeEventDescriptor.stringValue {
42 | guard let url = URL(string: urlStr) else { return }
43 | let oauthCompletion: DropboxOAuthCompletion = { [weak self] in
44 | if let authResult = $0 {
45 | switch authResult {
46 | case .success:
47 | print("Success! User is logged into DropboxClientsManager.")
48 | self?.userAuthed = true
49 | case .cancel:
50 | print("Authorization flow was manually canceled by user!")
51 | self?.userAuthed = false
52 | case .error(_, let description):
53 | print("Error: \(String(describing: description))")
54 | self?.userAuthed = false
55 | }
56 | }
57 | }
58 |
59 | switch appPermission {
60 | case .fullDropboxScoped:
61 | DropboxClientsManager.handleRedirectURL(url, completion: oauthCompletion)
62 | case .fullDropboxScopedForTeamTesting:
63 | DropboxClientsManager.handleRedirectURLTeam(url, completion: oauthCompletion)
64 | }
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/macOS/ContentView.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import SwiftUI
6 | import SwiftyDropbox
7 |
8 | struct ContentView: View {
9 | @EnvironmentObject var appDelegate: AppDelegate
10 | @ObservedObject var viewModel = ViewModel()
11 |
12 | var body: some View {
13 | if viewModel.isLinked || appDelegate.userAuthed {
14 | VStack {
15 | Button("Run API Tests", action: runApiTests)
16 | .padding()
17 | Button("Unlink Dropbox Account", action: unlink)
18 | .padding()
19 | }
20 | .padding()
21 | } else {
22 | Button("Link Dropbox (pkce code flow)", action: link)
23 | .padding()
24 | }
25 | }
26 |
27 | func runApiTests() {
28 | let unlink = {
29 | DropboxClientsManager.unlinkClients()
30 | viewModel.checkIsLinked()
31 | appDelegate.userAuthed = false
32 | exit(0)
33 | }
34 |
35 | switch appPermission {
36 | case .fullDropboxScoped:
37 | DropboxTester().testAllUserEndpoints(asMember: false, nextTest: unlink)
38 | case .fullDropboxScopedForTeamTesting:
39 | DropboxTeamTester().testTeamMemberFileAcessActions(unlink)
40 | }
41 | }
42 |
43 | func unlink() {
44 | DropboxClientsManager.unlinkClients()
45 | viewModel.checkIsLinked()
46 | appDelegate.userAuthed = false
47 | }
48 |
49 | func link() {
50 | let scopeRequest: ScopeRequest
51 | // note if you add new scopes, you need to relogin to update your token
52 | switch appPermission {
53 | case .fullDropboxScoped:
54 | scopeRequest = ScopeRequest(scopeType: .user, scopes: DropboxTester.scopes, includeGrantedScopes: false)
55 | case .fullDropboxScopedForTeamTesting:
56 | scopeRequest = ScopeRequest(scopeType: .team, scopes: DropboxTeamTester.scopes, includeGrantedScopes: false)
57 | }
58 |
59 | DropboxClientsManager.authorizeFromControllerV2(
60 | sharedApplication: NSApplication.shared,
61 | controller: nil,
62 | loadingStatusDelegate: nil,
63 | openURL: { (url: URL) -> Void in NSWorkspace.shared.open(url) },
64 | scopeRequest: scopeRequest
65 | )
66 | }
67 | }
68 |
69 | class ViewModel: ObservableObject {
70 | @Published var isLinked: Bool
71 |
72 | init() {
73 | self.isLinked = ViewModel.sdkIsLinked()
74 | }
75 |
76 | func checkIsLinked() {
77 | isLinked = ViewModel.sdkIsLinked()
78 | }
79 |
80 | private static func sdkIsLinked() -> Bool {
81 | DropboxClientsManager.authorizedClient != nil || DropboxClientsManager.authorizedTeamClient != nil
82 | }
83 | }
84 |
85 | struct ContentView_Previews: PreviewProvider {
86 | static var previews: some View {
87 | ContentView()
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleURLTypes
6 |
7 |
8 | CFBundleTypeRole
9 | Editor
10 | CFBundleURLSchemes
11 |
12 | db-<APP_KEY>
13 | db-<APP_KEY>
14 | db-<APP_KEY>
15 |
16 |
17 |
18 | LSApplicationQueriesSchemes
19 |
20 | dbapi-2
21 | dbapi-8-emm
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/macOS/TestSwiftyDropboxApp.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import SwiftUI
6 |
7 | @main
8 | struct TestSwiftyDropboxApp: App {
9 | @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
10 |
11 | var body: some Scene {
12 | WindowGroup {
13 | ContentView()
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_SwiftUI/macOS/macOS.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOS/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOS/FileBrowserView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2023 Dropbox. All rights reserved.
3 | //
4 |
5 | import SwiftUI
6 |
7 | @available(iOS 16.0, *)
8 | func MakeFileBrowserView(localURL: URL?) -> FileBrowserView {
9 | FileBrowserView(viewModel: FileBrowserViewModel(localURL: localURL))
10 | }
11 |
12 | @available(iOS 16.0, *)
13 | class FileBrowserViewModel: ObservableObject {
14 | let localURL: URL?
15 | @Published var files: [URL] = []
16 | @Published var showAlert = false
17 | @Published var selectedFileContent: String = ""
18 |
19 | init(localURL: URL?) {
20 | self.localURL = localURL
21 |
22 | let fileManager = FileManager.default
23 |
24 | guard let localURL = localURL else {
25 | return
26 | }
27 |
28 | do {
29 | let fileURLs = try fileManager.contentsOfDirectory(at: localURL, includingPropertiesForKeys: nil)
30 | self.files = fileURLs.sorted(by: { $0.lastPathComponent < $1.lastPathComponent })
31 | } catch {
32 | print("Error loading files: \(error)")
33 | }
34 | }
35 |
36 | func showFile(fileURL: URL) -> () -> Void {
37 | {
38 | do {
39 | self.selectedFileContent = String(try String(contentsOf: fileURL).prefix(10_000))
40 | self.showAlert = true
41 | } catch {
42 | print("Error reading file: \(error)")
43 | }
44 | }
45 | }
46 | }
47 |
48 | @available(iOS 16.0, *)
49 | struct FileBrowserView: View {
50 | @Environment(\.dismiss) private var dismiss
51 | @ObservedObject var viewModel: FileBrowserViewModel
52 |
53 | var body: some View {
54 | NavigationView {
55 | VStack {
56 | Text("Files Count: \(viewModel.files.count)")
57 | if viewModel.files.isEmpty {
58 | Text("Folder doesn't exist or is empty")
59 | .foregroundColor(.red)
60 | } else {
61 | List(viewModel.files, id: \.self) { fileURL in
62 | Button(action: viewModel.showFile(fileURL: fileURL)) {
63 | Text(fileURL.lastPathComponent)
64 | }
65 | }
66 | }
67 | }
68 | .alert(isPresented: $viewModel.showAlert) {
69 | Alert(title: Text("File Content"), message: Text(viewModel.selectedFileContent), dismissButton: .default(Text("Close")))
70 | }
71 | .toolbar {
72 | ToolbarItem(placement: .navigationBarLeading) {
73 | Button("Close") {
74 | dismiss()
75 | }
76 | }
77 | }
78 | }
79 | }
80 | }
81 |
82 | @available(iOS 16.0, *)
83 | struct FileBrowserView_Previews: PreviewProvider {
84 | static var previews: some View {
85 | FileBrowserView(viewModel: FileBrowserViewModel(localURL: nil))
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleURLTypes
22 |
23 |
24 | CFBundleTypeRole
25 | Editor
26 | CFBundleURLSchemes
27 |
28 | db-<APP_KEY>
29 | db-<APP_KEY>
30 | db-<APP_KEY>
31 |
32 |
33 |
34 | CFBundleVersion
35 | 1
36 | LSApplicationQueriesSchemes
37 |
38 | dbapi-2
39 | dbapi-8-emm
40 |
41 | LSRequiresIPhoneOS
42 |
43 | UILaunchStoryboardName
44 | LaunchScreen
45 | UIMainStoryboardFile
46 | Main
47 | UIRequiredDeviceCapabilities
48 |
49 | armv7
50 |
51 | UISupportedInterfaceOrientations
52 |
53 | UIInterfaceOrientationPortrait
54 | UIInterfaceOrientationLandscapeLeft
55 | UIInterfaceOrientationLandscapeRight
56 |
57 | UISupportedInterfaceOrientations~ipad
58 |
59 | UIInterfaceOrientationPortrait
60 | UIInterfaceOrientationPortraitUpsideDown
61 | UIInterfaceOrientationLandscapeLeft
62 | UIInterfaceOrientationLandscapeRight
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOS/TestSwiftyDropbox.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)(null)
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOS/TestUtilities.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2023 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Foundation
6 |
7 | public enum TestConstants {
8 | public static var sharedContainerDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: TestData.sharedContainerIdentifier)!
9 | public static var cachesDirectory = sharedContainerDirectory.appendingPathComponent("Caches")
10 | public static var fileToUpload = cachesDirectory.appendingPathComponent("file.txt")
11 | public static var dropboxTestFolder = "/background_session_testing"
12 | public static var localDownloadFolder = cachesDirectory.appendingPathComponent("downloads")
13 | }
14 |
15 | public class TestUtilities {
16 | public static func createFileToUpload(sizeInKBs: Double) {
17 | let sizeInBytes = Int(1_024 * sizeInKBs)
18 | writeFile(ofSize: sizeInBytes, at: TestConstants.fileToUpload)
19 | }
20 |
21 | public static func writeFile(ofSize size: Int, at url: URL) {
22 | let content = "test_content"
23 | let contentData = content.data(using: .utf8)!
24 | let dataSize = contentData.count
25 |
26 | do {
27 | let repeatCount = size / dataSize
28 | let fileContent = String(repeating: content, count: repeatCount)
29 |
30 | try fileContent.write(to: url, atomically: true, encoding: .utf8)
31 | } catch {
32 | print("Error writing file: \(error)")
33 | }
34 | }
35 |
36 | public static func summary(of route: String, from response: CustomStringConvertible?, error: CustomStringConvertible?) -> String {
37 | "\(route) response: \(response?.description ?? "nil") error: \(error?.description ?? "nil")"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOSTests/CustomRoutesTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2022 Dropbox Inc. All rights reserved.
3 | //
4 |
5 | import Foundation
6 |
7 | import XCTest
8 | #if os(OSX)
9 | @testable import TestSwiftyDropbox_macOS
10 | #elseif os(iOS)
11 | @testable import TestSwiftyDropbox_iOS
12 | #endif
13 |
14 | @testable import SwiftyDropbox
15 |
16 | class CustomRoutesTests: XCTestCase {
17 | private var userClient: UsersRoutes!
18 | private var tester: DropboxTester!
19 |
20 | override func setUp() {
21 | // You need an API app with the "Full Dropbox" permission type and at least the scopes in DropboxTester.scopes
22 | // and no team scopes.
23 | // You can create one for testing here: https://www.dropbox.com/developers/apps/create
24 | // The 'App key' will be on the app's info page.
25 | // Then follow https://dropbox.tech/developers/pkce--what-and-why- to get a refresh token using the PKCE flow
26 |
27 | continueAfterFailure = false
28 |
29 | if DropboxClientsManager.authorizedClient == nil {
30 | setupDropboxClientsManager()
31 | }
32 |
33 | userClient = DropboxClientsManager.authorizedClient!.users!
34 | tester = DropboxTester()
35 | }
36 |
37 | func setupDropboxClientsManager() {
38 | let processInfo = ProcessInfo.processInfo.environment
39 |
40 | guard let apiAppKey = processInfo["FULL_DROPBOX_API_APP_KEY"] else {
41 | return XCTFail("FULL_DROPBOX_API_APP_KEY needs to be set in the test Scheme")
42 | }
43 | guard let refreshToken = processInfo["FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN"] else {
44 | return XCTFail("FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN needs to be set in the test Scheme")
45 | }
46 |
47 | guard let transportClient = TestAuthTokenGenerator.transportClient(with: refreshToken, apiKey: apiAppKey, scopes: DropboxTester.scopes) else {
48 | return XCTFail("Error: Access token creation failed")
49 | }
50 |
51 | #if os(OSX)
52 | DropboxClientsManager.setupWithAppKeyDesktop(apiAppKey, transportClient: transportClient, secureStorageAccess: SecureStorageAccessTestImpl())
53 | #elseif os(iOS)
54 | DropboxClientsManager.setupWithAppKey(apiAppKey, transportClient: transportClient, secureStorageAccess: SecureStorageAccessTestImpl())
55 | #endif
56 | }
57 |
58 | override func tearDown() {
59 | print("tearDown: delete folder")
60 | let flag = XCTestExpectation()
61 |
62 | FilesTests(tester: tester).deleteV2 {
63 | flag.fulfill()
64 | }
65 |
66 | _ = XCTWaiter.wait(for: [flag], timeout: 30) // don't need to check result on tear down
67 | }
68 |
69 | func testFileRoutes() {
70 | let flag = XCTestExpectation()
71 |
72 | let nextTest = {
73 | flag.fulfill()
74 | }
75 |
76 | tester.testCustomActions(nextTest)
77 |
78 | let result = XCTWaiter.wait(for: [flag], timeout: 60 * 5)
79 | XCTAssertEqual(result, .completed, "Error: timeout on file routes tests")
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOSTests/FilesRoutesTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FilesRoutesTests.swift
3 | // FilesRoutesTests
4 | //
5 | // Created by jlocke on 5/20/21.
6 | // Copyright © 2021 Dropbox. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | #if os(OSX)
11 | @testable import TestSwiftyDropbox_macOS
12 | #elseif os(iOS)
13 | @testable import TestSwiftyDropbox_iOS
14 | #endif
15 |
16 | @testable import SwiftyDropbox
17 |
18 | class FilesRoutesTests: XCTestCase {
19 | private var userClient: UsersRoutes!
20 | private var tester: DropboxTester!
21 |
22 | override func setUp() {
23 | // You need an API app with the "Full Dropbox" permission type and at least the scopes in DropboxTester.scopes
24 | // and no team scopes.
25 | // You can create one for testing here: https://www.dropbox.com/developers/apps/create
26 | // The 'App key' will be on the app's info page.
27 | // Then follow https://dropbox.tech/developers/pkce--what-and-why- to get a refresh token using the PKCE flow
28 |
29 | continueAfterFailure = false
30 |
31 | if DropboxClientsManager.authorizedClient == nil {
32 | setupDropboxClientsManager()
33 | }
34 |
35 | userClient = DropboxClientsManager.authorizedClient!.users!
36 | tester = DropboxTester()
37 | }
38 |
39 | func setupDropboxClientsManager() {
40 | let processInfo = ProcessInfo.processInfo.environment
41 |
42 | guard let apiAppKey = processInfo["FULL_DROPBOX_API_APP_KEY"] else {
43 | return XCTFail("FULL_DROPBOX_API_APP_KEY needs to be set in the test Scheme")
44 | }
45 | guard let refreshToken = processInfo["FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN"] else {
46 | return XCTFail("FULL_DROPBOX_TESTER_USER_REFRESH_TOKEN needs to be set in the test Scheme")
47 | }
48 |
49 | guard let transportClient = TestAuthTokenGenerator.transportClient(with: refreshToken, apiKey: apiAppKey, scopes: DropboxTester.scopes) else {
50 | return XCTFail("Error: Access token creation failed")
51 | }
52 |
53 | #if os(OSX)
54 | DropboxClientsManager.setupWithAppKeyDesktop(apiAppKey, transportClient: transportClient, secureStorageAccess: SecureStorageAccessTestImpl())
55 | #elseif os(iOS)
56 | DropboxClientsManager.setupWithAppKey(apiAppKey, transportClient: transportClient, secureStorageAccess: SecureStorageAccessTestImpl())
57 | #endif
58 | }
59 |
60 | override func tearDown() {
61 | print("tearDown: delete folder")
62 | let flag = XCTestExpectation()
63 |
64 | FilesTests(tester: tester).deleteV2 {
65 | flag.fulfill()
66 | }
67 |
68 | _ = XCTWaiter.wait(for: [flag], timeout: 30) // don't need to check result on tear down
69 | }
70 |
71 | func testFileRoutes() {
72 | let flag = XCTestExpectation()
73 |
74 | let nextTest = {
75 | flag.fulfill()
76 | }
77 |
78 | tester.testFilesActions(nextTest, asMember: false)
79 |
80 | let result = XCTWaiter.wait(for: [flag], timeout: 60 * 5)
81 | XCTAssertEqual(result, .completed, "Error: timeout on file routes tests")
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOSTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOSTests/ObjCFilesRoutesTests.h:
--------------------------------------------------------------------------------
1 | //
2 | // ObjCUserRoutesTests.h
3 | // TestSwiftyDropbox
4 | //
5 | // Created by Taylor Case on 10/11/22.
6 | // Copyright © 2022 Dropbox. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ObjCFilesRoutesTests : XCTestCase
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOSTests/ObjCTeamRoutesTests.h:
--------------------------------------------------------------------------------
1 | //
2 | // ObjCTeamRoutesTests.h
3 | // TestSwiftyDropbox
4 | //
5 | // Created by Taylor Case on 12/16/22.
6 | // Copyright © 2022 Dropbox. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ObjCTeamRoutesTests : XCTestCase
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_iOSTests/SwiftyDropboxTestExtensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestSecureStorageAccess.swift
3 | // TestSwiftyDropbox
4 | //
5 | // Created by jlocke on 12/13/23.
6 | // Copyright © 2023 Dropbox. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SwiftyDropbox
11 | import SwiftyDropboxObjC
12 |
13 | public extension DBXDropboxOAuthManager {
14 | @objc
15 | static func __test_only_resetForTeamSetup() {
16 | DropboxOAuthManager.sharedOAuthManager = nil
17 | }
18 | }
19 |
20 | @objc
21 | public class DBXSecureStorageAccessTestImpl: DBXSecureStorageAccessImpl {
22 | @objc
23 | public convenience init() {
24 | self.init(swift: SecureStorageAccessTestImpl())
25 | }
26 |
27 | fileprivate init(swift: SecureStorageAccessTestImpl) {
28 | super.init(swift: swift)
29 | }
30 | }
31 |
32 | public class SecureStorageAccessTestImpl: SecureStorageAccess {
33 | private static var accessTokenData: Data?
34 |
35 | public init() {}
36 |
37 | public func checkAccessibilityMigrationOneTime() {}
38 |
39 | public func setAccessTokenData(for userId: String, data: Data) -> Bool {
40 | Self.accessTokenData = data
41 | return true
42 | }
43 |
44 | public func getAllUserIds() -> [String] {
45 | [TestAuthTokenGenerator.testUid]
46 | }
47 |
48 | public func getDropboxAccessToken(for key: String) -> DropboxAccessToken? {
49 | guard let accessTokenData = Self.accessTokenData else {
50 | return nil
51 | }
52 |
53 | let jsonDecoder = JSONDecoder()
54 | return try? jsonDecoder.decode(DropboxAccessToken.self, from: accessTokenData)
55 | }
56 |
57 | public func deleteInfo(for key: String) -> Bool {
58 | true
59 | }
60 |
61 | public func deleteInfoForAllKeys() -> Bool {
62 | true
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_macOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | ///
2 | /// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
3 | ///
4 |
5 | import Cocoa
6 | import SwiftyDropbox
7 |
8 | @NSApplicationMain
9 | class AppDelegate: NSObject, NSApplicationDelegate {
10 | var viewController: ViewController?
11 |
12 | func applicationDidFinishLaunching(_ aNotification: Notification) {
13 | let processInfo = ProcessInfo.processInfo.environment
14 | let inTestScheme = processInfo["FULL_DROPBOX_API_APP_KEY"] != nil
15 |
16 | // Skip setup if launching for unit tests, XCTests set up the clients themselves
17 | if inTestScheme {
18 | return
19 | }
20 |
21 | if TestData.fullDropboxAppKey.range(of: "<") != nil {
22 | print("\n\n\nMust set test data (in TestData.swift) before launching app.\n\n\nTerminating.....\n\n")
23 | exit(0)
24 | }
25 | switch appPermission {
26 | case .fullDropboxScoped:
27 | DropboxClientsManager.setupWithAppKeyDesktop(TestData.fullDropboxAppKey)
28 | case .fullDropboxScopedForTeamTesting:
29 | DropboxClientsManager.setupWithTeamAppKeyDesktop(TestData.fullDropboxAppKey)
30 | }
31 | NSAppleEventManager.shared()
32 | .setEventHandler(
33 | self,
34 | andSelector: #selector(handleGetURLEvent),
35 | forEventClass: AEEventClass(kInternetEventClass),
36 | andEventID: AEEventID(kAEGetURL)
37 | )
38 |
39 | viewController = NSApplication.shared.windows[0].contentViewController as? ViewController
40 | checkButtons()
41 | }
42 |
43 | @objc func handleGetURLEvent(_ event: NSAppleEventDescriptor?, replyEvent: NSAppleEventDescriptor?) {
44 | if let aeEventDescriptor = event?.paramDescriptor(forKeyword: AEKeyword(keyDirectObject)) {
45 | if let urlStr = aeEventDescriptor.stringValue {
46 | let url = URL(string: urlStr)!
47 | let oauthCompletion: DropboxOAuthCompletion = {
48 | if let authResult = $0 {
49 | switch authResult {
50 | case .success:
51 | print("Success! User is logged into Dropbox.")
52 | case .cancel:
53 | print("Authorization flow was manually canceled by user!")
54 | case .error(_, let description):
55 | print("Error: \(String(describing: description))")
56 | }
57 | }
58 | self.checkButtons()
59 | }
60 |
61 | switch appPermission {
62 | case .fullDropboxScoped:
63 | DropboxClientsManager.handleRedirectURL(url, includeBackgroundClient: false, completion: oauthCompletion)
64 | case .fullDropboxScopedForTeamTesting:
65 | DropboxClientsManager.handleRedirectURLTeam(url, completion: oauthCompletion)
66 | }
67 | }
68 | }
69 | }
70 |
71 | func applicationWillTerminate(_ aNotification: Notification) {
72 | // Insert code here to tear down your application
73 | }
74 |
75 | func checkButtons() {
76 | viewController?.checkButtons()
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_macOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSApplicationQueriesSchemes
6 |
7 | dbapi-2
8 | dbapi-8-emm
9 |
10 | CFBundleURLTypes
11 |
12 |
13 | CFBundleTypeRole
14 | Editor
15 | CFBundleURLSchemes
16 |
17 | db-<APP_KEY>
18 | db-<APP_KEY>
19 | db-<APP_KEY>
20 |
21 |
22 |
23 | CFBundleDevelopmentRegion
24 | en
25 | CFBundleExecutable
26 | $(EXECUTABLE_NAME)
27 | CFBundleIconFile
28 |
29 | CFBundleIdentifier
30 | $(PRODUCT_BUNDLE_IDENTIFIER)
31 | CFBundleInfoDictionaryVersion
32 | 6.0
33 | CFBundleName
34 | $(PRODUCT_NAME)
35 | CFBundlePackageType
36 | APPL
37 | CFBundleShortVersionString
38 | 1.0
39 | CFBundleVersion
40 | 1
41 | LSMinimumSystemVersion
42 | $(MACOSX_DEPLOYMENT_TARGET)
43 | NSHumanReadableCopyright
44 | Copyright © 2017 Dropbox. All rights reserved.
45 | NSMainStoryboardFile
46 | Main
47 | NSPrincipalClass
48 | NSApplication
49 |
50 |
51 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestSwiftyDropbox_macOSTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TestSwiftyDropbox/TestUtils/TestTokenAuthGenerator.swift:
--------------------------------------------------------------------------------
1 | @testable import SwiftyDropbox
2 | import XCTest
3 |
4 | enum TestAuthTokenGenerator {
5 | static let testUid = "test" // non-empty string needed here as subsequent tokens will share the uid and macOS keychain drops the attribute if empty
6 |
7 | static func transportClient(with refreshToken: String, apiKey: String, scopes: [String]) -> DropboxTransportClient? {
8 | let manager = SwiftyDropbox.DropboxOAuthManager(appKey: apiKey, secureStorageAccess: SecureStorageAccessTestImpl())
9 |
10 | let defaultToken = DropboxAccessToken(
11 | accessToken: "",
12 | uid: Self.testUid,
13 | refreshToken: refreshToken,
14 | tokenExpirationTimestamp: 0
15 | )
16 |
17 | let flag = XCTestExpectation()
18 |
19 | var returnAccessToken: DropboxAccessToken?
20 |
21 | manager.refreshAccessToken(
22 | defaultToken,
23 | scopes: scopes,
24 | queue: DispatchQueue.global(qos: .userInitiated)
25 | ) { result in
26 |
27 | switch result {
28 | case .success(let authToken)?:
29 | returnAccessToken = authToken
30 | case .error(_, let description)?:
31 | XCTFail("Error: failed to refresh access token (\(description ?? "no description")")
32 | case .cancel?:
33 | XCTFail("Error: failed to refresh access token (cancelled)")
34 | case .none:
35 | XCTFail("Error: failed to refresh access token (no result)")
36 | }
37 |
38 | flag.fulfill()
39 | }
40 |
41 | let result = XCTWaiter.wait(for: [flag], timeout: 10)
42 | XCTAssertEqual(result, .completed, "Error: timeout refreshing access token")
43 | guard let accessToken = returnAccessToken else {
44 | XCTFail("AccessToken creation failed")
45 | fatalError("AccessToken creation failed")
46 | }
47 | return DropboxTransportClientImpl(accessTokenProvider: manager.accessTokenProviderForToken(accessToken))
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/update_repo_check.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Release checklist
4 | #
5 | # 1. Make sure test data is reset
6 | # 2. Run generator
7 | # 3. Check test project, run unit tests
8 | # 4. Check pod spec lint
9 | # 5. Increment version with script
10 | # 6. Update Carthage example project
11 | # 7. Push to CocoaPods
12 | #
13 |
14 | cat TestSwiftyDropbox/IntegrationTests/TestData.swift
15 |
16 | # python generate_base_client.py
17 |
18 | # pod spec lint
19 |
--------------------------------------------------------------------------------
/update_version.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Script for updating SwiftyDropbox version number
4 |
5 | echo
6 |
7 | if [ "$#" -ne 1 ]; then
8 | echo "Requires 1 parameter. Usage: \`./update_version \`"
9 | exit 1
10 | fi
11 |
12 | arg_version_regex="^[0-9]+\.[0-9]+\.[0-9]+$"
13 | version_regex="[0-9]+\.[0-9]+\.[0-9]+"
14 |
15 | podspec=./SwiftyDropbox.podspec
16 | objc_podspec=./SwiftyDropboxObjC.podspec
17 | readme=./README.md
18 | user_agent=Source/SwiftyDropbox/Shared/Handwritten/SDKConstants.swift
19 | ios_version=Source/SwiftyDropbox/Platform/SwiftyDropbox_iOS/Info.plist
20 | mac_version=Source/SwiftyDropbox/Platform/SwiftyDropbox_macOS/Info.plist
21 | ios_objc_version=Source/SwiftyDropboxObjC/Platform/SwiftyDropbox_iOS/Info.plist
22 | mac_objc_version=Source/SwiftyDropboxObjC/Platform/SwiftyDropbox_macOS/Info.plist
23 |
24 |
25 | if ! [[ $1 =~ $arg_version_regex ]]; then
26 | echo "\"$1\" version string must have format x.x.x"
27 | exit 1
28 | else
29 | echo "Updating SDK text to version \"$1\""
30 | fi
31 |
32 | echo
33 | echo
34 |
35 | echo "Replacing podspec version number..."
36 | sed -i '' -E "s/s.version = '$version_regex'/s.version = '$1'/" $podspec
37 | echo '--------------------'
38 | cat $podspec | grep $1
39 | echo '--------------------'
40 | echo
41 |
42 | echo "Replacing ObjC podspec version number..."
43 | sed -i '' -E "s/s.version = '$version_regex'/s.version = '$1'/" $objc_podspec
44 | sed -i '' -E "s/s.dependency 'SwiftyDropbox', '~> $version_regex'/s.dependency 'SwiftyDropbox', '~> $1'/" $objc_podspec
45 | echo '--------------------'
46 | cat $objc_podspec | grep $1
47 | echo '--------------------'
48 | echo
49 |
50 | echo "Replacing README version number..."
51 | sed -i '' -E "s/~> $version_regex/~> $1/" $readme
52 | echo '--------------------'
53 | cat $readme | grep $1
54 | echo '--------------------'
55 | echo
56 |
57 | echo "Replacing User Agent version number..."
58 | sed -i '' -E "s/versionSDK = \"$version_regex\"/versionSDK = \"$1\"/" $user_agent
59 | echo '--------------------'
60 | cat $user_agent | grep $1
61 | echo '--------------------'
62 | echo
63 |
64 | echo "Replacing iOS xcodeproj version number..."
65 | sed -i '' -E "s/$version_regex/$1/" $ios_version
66 | echo '--------------------'
67 | cat $ios_version | grep $1
68 | echo '--------------------'
69 | echo
70 |
71 | echo "Replacing macOS xcodeproj version number..."
72 | sed -i '' -E "s/$version_regex/$1/" $mac_version
73 | echo '--------------------'
74 | cat $mac_version | grep $1
75 | echo '--------------------'
76 | echo
77 |
78 | echo "Replacing iOS objc xcodeproj version number..."
79 | sed -i '' -E "s/$version_regex/$1/" $ios_objc_version
80 | echo '--------------------'
81 | cat $ios_objc_version | grep $1
82 | echo '--------------------'
83 | echo
84 |
85 | echo "Replacing macOS objc xcodeproj version number..."
86 | sed -i '' -E "s/$version_regex/$1/" $mac_objc_version
87 | echo '--------------------'
88 | cat $mac_objc_version | grep $1
89 | echo '--------------------'
90 | echo
91 |
92 | echo
93 | echo "Committing changes and tagging commit."
94 | git commit -am "$1 release."
95 | git tag "$1"
96 | echo
97 | echo "Changes ready for review and push"
98 | echo
99 |
--------------------------------------------------------------------------------