Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
b3fd03c
refactor: migrate share extension to SwiftUI
marinofaggiana Oct 28, 2026
a5cc902
fix: enable Share extension previews in the Nextcloud scheme
marinofaggiana Oct 28, 2026
ebab7cd
feat: add folder tree and recent destinations to Share extension
marinofaggiana Oct 28, 2026
7395bbd
fix: load share extension capabilities and improve text import fallbacks
marinofaggiana Oct 28, 2026
b18419b
Merge branch 'master' into share-review-ext
marinofaggiana Oct 29, 2026
5d5dc3c
refactor: simplify share extension capability handling
marinofaggiana Oct 29, 2026
94dd633
fix: refine share extension folder selection and upload layout
marinofaggiana Oct 29, 2026
2b55388
fix: make cached share destinations usable during refresh
marinofaggiana Oct 29, 2026
6ac18e1
feat: improve share extension account menu and file previews
marinofaggiana Oct 29, 2026
69c8c72
fix: handle offline sharing and improve landscape layout
marinofaggiana Oct 29, 2026
07039b3
fix: improve Share extension landscape layout
marinofaggiana Oct 29, 2026
c136172
fix: open share file actions from the entire row
marinofaggiana Oct 29, 2026
2dab3b1
fix: present share file actions in a confirmation dialog
marinofaggiana Oct 29, 2026
f5e30ac
feat: prioritize and badge favorite folders in Share extension
marinofaggiana Oct 29, 2026
d201d5a
fix: improve Share extension folder browsing and upload feedback
marinofaggiana Oct 30, 2026
8f1ae5b
chore: remove Share folder timing logs and update launch path
marinofaggiana Oct 30, 2026
f0b42aa
Merge branch 'master' into share-review-ext
marinofaggiana Oct 30, 2026
63aaf3d
chore: track NextcloudKit main branch
marinofaggiana Oct 30, 2026
665123d
fix: improve share extension errors and destination readiness
marinofaggiana Oct 30, 2026
743fb90
refactor: remove legacy UIKit share extension
marinofaggiana Oct 30, 2026
fdeebad
chore: trim Share extension dependencies and update contributor docs
marinofaggiana Oct 30, 2026
a9d2f4f
scheme
marinofaggiana Oct 30, 2026
6027a10
Merge branch 'master' into share-review-ext
marinofaggiana Oct 31, 2026
938a660
fix: show cached share destinations before loading capabilities
marinofaggiana Nov 1, 2026
d45305f
fix: prepare share extension before appearance and avoid loading flicker
marinofaggiana Nov 1, 2026
e12edad
refactor: simplify share extension state and lifecycle
marinofaggiana Nov 1, 2026
bc6897c
docs: clarify Share extension lifecycle and upload flow
marinofaggiana Nov 1, 2026
6ab1418
refactor: remove unused sources and resources from Share extension
marinofaggiana Nov 1, 2026
f0a1ca2
fix: improve Share extension browsing and filename display
marinofaggiana Nov 7, 2026
1bdd17a
Merge branch 'master' into share-review-ext
marinofaggiana Nov 9, 2026
b5e2284
fix: cancel share operations when the selected account is removed
marinofaggiana Nov 9, 2026
874b3ff
refactor: simplify share extension state management
marinofaggiana Nov 9, 2026
c481e18
fix: ensure shared UTF-8 text uses a txt extension
marinofaggiana Nov 9, 2026
eb78d87
Merge branch 'master' into share-review-ext
marinofaggiana Nov 9, 2026
c2492fd
refactor: improve share upload conflict layout and actions
marinofaggiana Nov 9, 2026
fc78c2a
fix: left-align capability errors in share extension
marinofaggiana Nov 9, 2026
1f657b2
fix: improve Share extension passcode and biometric authentication
marinofaggiana Nov 10, 2026
bbf0302
refactor: simplify Share extension state and upload flow
marinofaggiana Nov 10, 2026
df6e70e
Merge branch 'master' into share-review-ext
marinofaggiana Nov 10, 2026
be7be74
test: use AppConfig login for passcode UI tests
marinofaggiana Nov 10, 2026
d88e168
ci: extend Xcode test timeouts and remove explicit test iterations
marinofaggiana Nov 10, 2026
b06590d
ci: validate app password login before passcode tests
marinofaggiana Nov 10, 2026
207a9d9
Merge branch 'master' into share-review-ext
marinofaggiana Nov 10, 2026
b1f50dc
fix: avoid Photos permission prompt during background upload cleanup
marinofaggiana Nov 10, 2026
6f99bc7
test: allow 90 seconds for AppConfig login in CI
marinofaggiana Nov 11, 2026
b44bf19
ci: use Xcode 27.2 and iOS 27.2 simulator
marinofaggiana Nov 11, 2026
67dfaaa
ci: restore bounded Xcode test timeouts
marinofaggiana Nov 11, 2026
6928107
ci: run only unit tests in GitHub Actions
marinofaggiana Nov 11, 2026
eef15d8
Merge branch 'master' into share-review-ext
marinofaggiana Nov 11, 2026
9b4197c
Merge branch 'master' into share-review-ext
marinofaggiana Nov 12, 2026
1e5b033
chore: bump marketing version to 35.3.0
marinofaggiana Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 6 additions & 58 deletions .github/workflows/xcode.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ on:

env:
PROJECT: Nextcloud.xcodeproj
DESTINATION: platform=iOS Simulator,name=iPhone 17,OS=27.0
DESTINATION: platform=iOS Simulator,name=iPhone 17,OS=27.2
SCHEME: Nextcloud
XCODE_VERSION: '27.1'
XCODE_VERSION: '27.2'
SERVER_BRANCH: stable30
PHP_VERSION: 8.3

Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
retention-days: 4

test:
name: Run Tests
name: Run Unit Tests
runs-on: xcode-27
timeout-minutes: 40
needs: [build]
Expand All @@ -69,42 +69,6 @@ jobs:

steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Detect passcode changes
id: passcode_changes
shell: bash
env:
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PUSH_BEFORE_SHA: ${{ github.event.before }}
run: |
run_passcode_tests=false
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
compare_base=$(git merge-base "$PR_BASE_SHA" "$PR_HEAD_SHA")
compare_head="$PR_HEAD_SHA"
else
compare_base="$PUSH_BEFORE_SHA"
compare_head="$GITHUB_SHA"
fi

if [ -z "$compare_base" ] || [ "$compare_base" = "0000000000000000000000000000000000000000" ]; then
run_passcode_tests=true
else
git diff --name-only -z "$compare_base" "$compare_head" > "$RUNNER_TEMP/passcode-changed-files"
while IFS= read -r -d '' changed_file; do
case "$changed_file" in
iOSClient/Utility/Passcode/* | \
Tests/NextcloudUITests/PasscodeUITests.swift)
run_passcode_tests=true
break
;;
esac
done < "$RUNNER_TEMP/passcode-changed-files"
fi
echo "run=$run_passcode_tests" >> "$GITHUB_OUTPUT"
echo "Run passcode UI tests: $run_passcode_tests"

- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0
Expand Down Expand Up @@ -166,33 +130,17 @@ jobs:
xcrun simctl boot "iPhone 17"
xcrun simctl bootstatus "iPhone 17" -b

- name: Check if Safari is installed
run: |
if xcrun simctl listapps booted | grep -q com.apple.mobilesafari; then
echo "Safari is installed in the simulator."
else
echo "Safari is NOT installed in the simulator."
exit 1
fi

- name: Run Xcode Test
- name: Run Xcode Unit Tests
timeout-minutes: 25
shell: bash
env:
RUN_PASSCODE_TESTS: ${{ steps.passcode_changes.outputs.run }}
run: |
set -o pipefail
test_selection=()
if [ "$RUN_PASSCODE_TESTS" != "true" ]; then
test_selection+=(-skip-testing:NextcloudUITests/PasscodeUITests)
fi
# UI tests remain available in the shared scheme for local execution.
xcodebuild test-without-building \
-xctestrun $(find . -type f -name "*.xctestrun") \
-destination "${{ env.DESTINATION }}" \
-derivedDataPath "DerivedData" \
"${test_selection[@]}" \
-test-iterations 3 \
-retry-tests-on-failure \
-only-testing:NextcloudUnitTests \
-test-timeouts-enabled YES \
-default-test-execution-time-allowance 600 \
-maximum-test-execution-time-allowance 600 \
Expand Down
5 changes: 4 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ Other platforms like Android are irrelevant for this project.
| `Brand` | Branding layer: `NCBrand.swift` (app constants, colors), `Database.swift` (Realm database name and schema version), Info.plists and entitlements for all targets, launch screen and intro screens. | Bump `databaseSchemaVersion` in `Brand/Database.swift` when changing Realm models. |
| `File Provider Extension` | Contains business logic for the iOS File Provider extension. | — |
| `File Provider Extension UI` | Contains UI logic for the iOS File Provider extension. | — |
| `Share` | Contains code for the iOS Share extension. | — |
| `Share` | Contains the active Share extension entry point, launched through `NSExtensionPrincipalClass`, plus input preparation, session storage and recent upload destinations. | — |
| `Share/View` | Contains the SwiftUI Share extension interface. | Select the `Nextcloud` scheme for Xcode previews. Shared Share sources are hosted by the app only in Debug (`SHARE_PREVIEWS`) and excluded from app Release builds. |
| `Share/Model` | Contains Share extension state, account handling and upload logic. | — |
| `Share/UIKit` | Contains the previous UIKit Share extension sources and storyboard for reference. | Keep these reference files out of the Share target build. |
| `Widget` | Contains code for iOS Widgets. | — |
| `WidgetDashboardIntentHandler` | Contains the intent handler for the dashboard widget. | — |
| `Notification Service Extension` | Contains the push notification service extension. | — |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ final class NCBackgroundUploadExtensionManager {
/// Disables the PhotoKit extension after the feature or auto upload is turned off and no jobs remain.
/// Active metadata defers disabling so cancellations and terminal results can still be reconciled.
func disableIfIdle() async -> Bool {
// Foreground cleanup must not trigger the initial Photos permission prompt.
guard PHPhotoLibrary.authorizationStatus(for: .readWrite) != .notDetermined else {
return false
}

let featureEnabled = NCPreferences().shouldUseBackgroundUploadExtension
let account = await database.getTableAccountAsync(predicate: NSPredicate(format: "autoUploadStart == true"))

Expand Down
8 changes: 5 additions & 3 deletions Brand/Share.plist
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSFaceIDUsageDescription</key>
<string>Face ID is required to authenticate using face recognition.</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<string>SUBQUERY (extensionItems, $extensionItem, SUBQUERY ($extensionItem.attachments, $attachment, (ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.data" OR ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text")).@count == $extensionItem.attachments.@count).@count &gt; 0</string>
</dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).NCShareEntryController</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.share-services</string>
</dict>
</dict>
</plist>
</plist>
Loading
Loading