chore(repo): improve contributor experience

This commit is contained in:
zarzet
2026-07-29 14:16:10 +07:00
parent 1e973d5ecb
commit 834a8dde89
20 changed files with 485 additions and 536 deletions
+24
View File
@@ -0,0 +1,24 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{dart,json,yaml,yml}]
indent_style = space
indent_size = 2
[*.{kt,kts,swift}]
indent_style = space
indent_size = 4
[*.go]
indent_style = tab
[*.md]
trim_trailing_whitespace = false
[*.{bat,cmd,ps1}]
end_of_line = crlf
+4
View File
@@ -1,5 +1,9 @@
* text=auto eol=lf
# Scripts executed on Unix runners must keep LF line endings.
*.sh text eol=lf
gradlew text eol=lf
# Windows scripts
*.bat text eol=crlf
*.cmd text eol=crlf
+61 -54
View File
@@ -1,30 +1,29 @@
name: Bug Report
description: Report a bug or unexpected behavior
description: Report a reproducible bug or unexpected behavior
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug! Please fill out the form below.
Thanks for reporting a SpotiFLAC Mobile bug. Please provide enough detail for another person to reproduce it.
- type: checkboxes
id: checklist
attributes:
label: Checklist
description: Please confirm the following before submitting
options:
- label: I have searched existing issues and this bug hasn't been reported yet
- label: I searched existing issues and did not find this bug.
required: true
- label: I am using the latest version of SpotiFLAC (Stable Version)
- label: I can reproduce this on the release channel selected below.
required: true
- type: textarea
id: description
attributes:
label: Bug Description
description: A clear and concise description of what the bug is
placeholder: Describe the bug...
label: Description
description: What happened, and what did you expect instead?
placeholder: Include the visible error and any relevant context.
validations:
required: true
@@ -32,29 +31,26 @@ body:
id: steps
attributes:
label: Steps to Reproduce
description: Steps to reproduce the behavior
placeholder: |
1. Go to '...'
2. Click on '...'
3. See error
1. Open ...
2. Enable ...
3. Tap ...
4. Observe ...
validations:
required: true
- type: textarea
id: expected
- type: dropdown
id: trigger
attributes:
label: Expected Behavior
description: What did you expect to happen?
placeholder: Describe what you expected...
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Behavior
description: What actually happened?
placeholder: Describe what actually happened...
label: Area
options:
- App startup
- Search or navigation
- Download or verification
- Library or metadata
- Playback or background service
- Audio analysis
- Other
validations:
required: true
@@ -62,62 +58,73 @@ body:
id: version
attributes:
label: App Version
description: Which version of SpotiFLAC are you using? (Check in Settings > About)
placeholder: "e.g., v2.2.0"
description: Find this in Settings > About.
placeholder: "e.g. 4.8.1 (139)"
validations:
required: true
- type: dropdown
id: platform
id: channel
attributes:
label: Platform
description: Which platform are you using?
label: Release Channel
options:
- Android
- iOS
- Stable
- Beta
- Local or development build
validations:
required: true
- type: input
id: device
attributes:
label: Device & OS Version
description: What device and OS version are you using?
placeholder: "e.g., Samsung Galaxy S24, Android 14"
label: Device and OS
placeholder: "e.g. Samsung Galaxy S24, Android 16"
validations:
required: true
- type: dropdown
id: download-service
id: storage
attributes:
label: Download Service
description: Which download service were you using when the bug occurred?
label: Download Storage
options:
- Tidal
- Qobuz
- Amazon Music
- Deezer (search only)
- SAF folder
- App-specific folder
- Not applicable
- Not sure
validations:
required: true
- type: dropdown
id: worker
attributes:
label: Download Worker
options:
- Native worker
- Dart worker
- Not applicable
- Not sure
validations:
required: true
- type: input
id: provider
attributes:
label: Extension or Provider
description: If relevant, include the extension/provider name and version.
placeholder: "Name, version, and selected priority"
- type: textarea
id: logs
attributes:
label: Logs / Screenshots
label: Logs and Media
description: |
If applicable, add logs or screenshots to help explain your problem.
**To get logs:**
1. Go to Settings > Options > Detailed Logging (turn ON)
2. Reproduce the bug
3. Go to Settings > Logs
4. Tap Share button to export logs
placeholder: Paste logs or drag & drop screenshots here...
Enable detailed logging, reproduce the problem, then export logs from Settings > Logs. For an Android cold-start crash, attach `adb logcat -b crash -d`. Add screenshots or a short recording when useful. Remove credentials and personal data first.
placeholder: Paste logs or drag files here.
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional Context
description: Any other context about the problem
placeholder: Add any other context...
placeholder: Settings, frequency, regression version, or anything else that may help.
+2 -2
View File
@@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: README
url: https://github.com/zarzet/SpotiFLAC-Mobile#readme
url: https://github.com/spotiflacapp/SpotiFLAC-Mobile#readme
about: Check the README for setup instructions and FAQ
- name: Extension Development Guide
url: https://spotiflac.zarz.moe/docs
about: Documentation for building SpotiFLAC extensions
about: Documentation for building SpotiFLAC Mobile extensions
+64 -51
View File
@@ -1,111 +1,124 @@
name: Download Issue
description: Report issues with downloading specific tracks or albums
description: Report a wrong, missing, failed, or low-quality download
title: "[Download]: "
labels: ["download-issue"]
body:
- type: markdown
attributes:
value: |
Having trouble downloading a specific track or album? Please provide details below.
Download matching is extension-driven. Include the source item, provider order, and logs so the exact decision path can be inspected.
- type: checkboxes
id: checklist
attributes:
label: Checklist
description: Please confirm the following before submitting
options:
- label: I have tried downloading with a different service (Tidal/Qobuz/Amazon)
- label: I searched existing issues and did not find this problem.
required: true
- label: I am using the latest version of SpotiFLAC (Stable Version)
- label: I updated the affected extension and retried once.
required: true
- type: dropdown
id: issue-type
attributes:
label: Issue Type
description: What kind of download issue are you experiencing?
options:
- Track not found on service
- Track or album not found
- Wrong track downloaded
- Download fails/errors
- Metadata incorrect
- Audio quality issue
- Download fails or stalls
- Metadata or cover is incorrect
- Audio format or quality is incorrect
- Duplicate or replacement behavior
- Other
validations:
required: true
- type: input
id: spotify-url
id: source-url
attributes:
label: Spotify URL
description: The Spotify URL of the track/album you're trying to download
placeholder: "https://open.spotify.com/track/..."
validations:
required: true
label: Source URL
description: URL pasted or opened in SpotiFLAC Mobile, if available.
placeholder: "https://..."
- type: input
id: track-info
attributes:
label: Track Info
description: Artist name and track title
placeholder: "Artist - Track Title"
label: Track or Album
placeholder: "Artist - Track or album title"
validations:
required: true
- type: input
id: metadata-source
attributes:
label: Search or Metadata Extension
placeholder: "Extension name and version"
validations:
required: true
- type: input
id: download-provider
attributes:
label: Selected Download Extension
placeholder: "Extension name and version"
validations:
required: true
- type: textarea
id: priority
attributes:
label: Provider Priority and Requested Quality
placeholder: |
Provider order: first, second, third
Requested quality: best / 24-bit / ...
Automatic fallback: on/off
validations:
required: true
- type: dropdown
id: download-service
id: storage
attributes:
label: Download Service
description: Which service did you try to download from?
label: Download Storage
options:
- Tidal
- Qobuz
- Amazon Music
- All services
- SAF folder
- App-specific folder
- Not sure
validations:
required: true
- type: dropdown
id: search-service
id: worker
attributes:
label: Search Service
description: Which search service are you using?
label: Download Worker
options:
- Spotify
- Deezer
- Native worker
- Dart worker
- Not sure
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: Describe the issue in detail
placeholder: |
What happened? What did you expect?
If wrong track was downloaded, what track was downloaded instead?
label: What Happened?
description: For a wrong match, identify both the expected and downloaded recording.
placeholder: Describe the result and the expected result.
validations:
required: true
- type: input
id: version
id: environment
attributes:
label: App Version
description: Which version of SpotiFLAC are you using?
placeholder: "e.g., v2.2.0"
label: App Version, Device, and OS
placeholder: "4.8.1 (139), device model, Android/iOS version"
validations:
required: true
- type: textarea
id: screenshots
id: logs
attributes:
label: Screenshots / Logs
description: |
If applicable, add screenshots or logs.
**To get logs:**
1. Go to Settings > Options > Detailed Logging (turn ON)
2. Try downloading the track again
3. Go to Settings > Logs
4. Tap Share button to export logs
placeholder: Drag & drop screenshots or paste logs here...
label: Logs and Screenshots
description: Enable detailed logging, retry once, and export Settings > Logs. Remove credentials and personal data.
placeholder: Paste logs or drag files here.
validations:
required: true
@@ -6,7 +6,7 @@ body:
- type: markdown
attributes:
value: |
Thanks for helping improve the SpotiFLAC Extension API!
Thanks for helping improve the SpotiFLAC Mobile Extension API!
This form is for extension developers who need new features or capabilities that don't exist yet.
- type: checkboxes
@@ -15,7 +15,7 @@ body:
label: Checklist
description: Please confirm the following before submitting
options:
- label: I have read the [Extension Development Guide](https://github.com/zarzet/SpotiFLAC-Mobile/blob/main/docs/EXTENSION_DEVELOPMENT.md)
- label: I have read the [Extension Development Guide](https://github.com/spotiflacapp/SpotiFLAC-Mobile/blob/main/docs/EXTENSION_DEVELOPMENT.md)
required: true
- label: I have searched existing issues and this API feature hasn't been requested yet
required: true
+1 -1
View File
@@ -50,7 +50,7 @@ body:
options:
- UI/UX Improvement
- Download Feature
- New Service Integration
- Extension System/API
- Metadata/Tagging
- Performance
- Settings/Configuration
+30 -15
View File
@@ -1,27 +1,42 @@
## Description
## Summary
<!-- What does this PR do? Why is it needed? -->
<!-- What changed, why is it needed, and which user-visible behavior is affected? -->
## Related Issues
<!-- Link related issues, e.g. "Fixes #123" -->
<!-- Use "Fixes #123" when this PR should close an issue. -->
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactor (no functional change)
- [ ] Documentation
- [ ] Other (describe below)
- [ ] Feature
- [ ] Performance improvement
- [ ] Refactor with no intended behavior change
- [ ] Tests, build, or repository maintenance
- [ ] Documentation or localization
## Checklist
## Validation
- [ ] Code follows project conventions
- [ ] `flutter analyze` and `flutter test` pass
- [ ] `go vet ./...` and `go test ./...` pass in `go_backend/` (if Go code changed)
- [ ] Documentation updated (if needed)
- [ ] Commit messages follow the [conventional commits](https://www.conventionalcommits.org) format
<!-- Check only commands relevant to this change. Explain skipped checks below. -->
## Screenshots
- [ ] `dart format --output=none --set-exit-if-changed lib test`
- [ ] `flutter analyze`
- [ ] `flutter test`
- [ ] `gofmt`, `go vet ./...`, and `go test ./...` in `go_backend/`
- [ ] Android or iOS native checks
- [ ] Manual reproduction or device test
<!-- For UI changes, add before/after screenshots. Delete this section otherwise. -->
Validation notes:
<!-- Devices, commands, test cases, or the reason a check was not applicable. -->
## Contributor Checklist
- [ ] This PR is focused and contains no unrelated changes.
- [ ] Extension-specific behavior, if any, uses a generic capability or manifest contract.
- [ ] User-facing strings, documentation, and generated files are updated where needed.
- [ ] No credentials, downloaded media, or build artifacts are included.
## Screenshots or Recordings
<!-- Add before/after media for UI changes. Delete this section otherwise. -->
+6 -3
View File
@@ -37,6 +37,7 @@ jobs:
- 'pubspec.lock'
- 'analysis_options.yaml'
- 'l10n.yaml'
- '.fvmrc'
- '.github/workflows/ci.yml'
go:
- 'go_backend/**'
@@ -51,6 +52,7 @@ jobs:
- 'lib/services/platform_bridge.dart'
- 'pubspec.yaml'
- 'pubspec.lock'
- '.fvmrc'
- '.github/workflows/ci.yml'
flutter:
@@ -67,6 +69,7 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version-file: .fvmrc
cache: true
- name: Cache pub dependencies
@@ -102,8 +105,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v6
with:
# Keep in sync with release.yml
go-version: "1.26.5"
go-version-file: go_backend/go.mod
cache-dependency-path: go_backend/go.sum
- name: Check formatting
@@ -134,13 +136,14 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: "1.26.5"
go-version-file: go_backend/go.mod
cache-dependency-path: go_backend/go.sum
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version-file: .fvmrc
cache: true
- name: Setup Gradle
+30 -14
View File
@@ -70,7 +70,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: "1.26.5"
go-version-file: go_backend/go.mod
cache-dependency-path: go_backend/go.sum
# Cache Gradle for faster builds
@@ -129,6 +129,7 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version-file: .fvmrc
cache: true
- name: Cache pub dependencies
@@ -146,13 +147,10 @@ jobs:
- name: Build APK (Release - unsigned)
run: |
flutter build apk --release --split-per-abi || true
# Verify APKs were created
flutter build apk --release --split-per-abi
ls -la build/app/outputs/flutter-apk/
if [ ! -f "build/app/outputs/flutter-apk/app-arm64-v8a-release.apk" ]; then
echo "ERROR: APK not found!"
exit 1
fi
test -f build/app/outputs/flutter-apk/app-arm64-v8a-release.apk
test -f build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk
- name: Sign APKs
uses: r0adkll/sign-android-release@v1
@@ -168,12 +166,29 @@ jobs:
- name: Rename APKs
run: |
VERSION=${{ needs.get-version.outputs.version }}
VERSION="${{ needs.get-version.outputs.version }}"
cd build/app/outputs/flutter-apk
# Signed files have -signed suffix
mv app-arm64-v8a-release-signed.apk SpotiFLAC-${VERSION}-arm64.apk || mv app-arm64-v8a-release.apk SpotiFLAC-${VERSION}-arm64.apk || true
mv app-armeabi-v7a-release-signed.apk SpotiFLAC-${VERSION}-arm32.apk || mv app-armeabi-v7a-release.apk SpotiFLAC-${VERSION}-arm32.apk || true
mv app-release-signed.apk SpotiFLAC-${VERSION}-universal.apk || mv app-release.apk SpotiFLAC-${VERSION}-universal.apk || true
rename_required_apk() {
unsigned="$1"
destination="$2"
signed="${unsigned%.apk}-signed.apk"
if [ -f "$signed" ]; then
mv "$signed" "$destination"
elif [ -f "$unsigned" ]; then
mv "$unsigned" "$destination"
else
echo "ERROR: Missing APK: $unsigned"
exit 1
fi
}
rename_required_apk \
app-arm64-v8a-release.apk \
"SpotiFLAC-${VERSION}-arm64.apk"
rename_required_apk \
app-armeabi-v7a-release.apk \
"SpotiFLAC-${VERSION}-arm32.apk"
ls -la
- name: Upload APK artifact
@@ -198,7 +213,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: "1.26.5"
go-version-file: go_backend/go.mod
cache-dependency-path: go_backend/go.sum
# Cache CocoaPods
@@ -274,6 +289,7 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version-file: .fvmrc
cache: true
- name: Cache pub dependencies
@@ -474,7 +490,7 @@ jobs:
jq --arg ver "$VERSION_NUM" \
--arg date "$DATE" \
--arg url "https://github.com/zarzet/SpotiFLAC-Mobile/releases/download/${VERSION}/SpotiFLAC-${VERSION}-ios-unsigned.ipa" \
--arg url "https://github.com/${{ github.repository }}/releases/download/${VERSION}/SpotiFLAC-${VERSION}-ios-unsigned.ipa" \
--argjson size "$IPA_SIZE" \
'.apps[0].version = $ver | .apps[0].versionDate = $date | .apps[0].downloadURL = $url | .apps[0].size = $size' \
apps.json > apps.json.tmp && mv apps.json.tmp apps.json
+70 -65
View File
@@ -1,93 +1,98 @@
# OS files
# Operating-system files
.DS_Store
Thumbs.db
Desktop.ini
# IDE
# Editors and local assistants
.idea/
.vscode/
*.iml
.cursorignore
.cursorrules
# Kiro specs (development only)
.kiro/
.playwright-mcp/
.rtk/
.claude/settings.local.json
CLAUDE.md
AGENTS.md
# Design assets (banners, mockups)
design/
# Reference folder (development only)
referensi/
# Documentation published separately. Keep the in-repo extension contract
# available because contribution templates link to it.
docs/*
!docs/EXTENSION_DEVELOPMENT.md
# Old spotiflac_android folder (moved to root)
spotiflac_android/
# Flutter/Dart
# Flutter and Dart
.dart_tool/
.fvm/
.packages
build/
*.lock
!pubspec.lock
.flutter-plugins
.flutter-plugins-dependencies
.metadata
/build/
/coverage/
*.apk
*.aab
*.ipa
# Go backend build artifacts
go_backend/*.aar
go_backend/*.jar
go_backend/*.exe
go_backend/*.xcframework/
# Local JavaScript tooling (the app itself has no Node dependency)
/node_modules/
/bun.lock
/package-lock.json
# Android
android/.gradle/
android/app/libs/gobackend.aar
android/app/libs/gobackend-sources.jar
android/local.properties
android/*.iml
android/key.properties
android/*.jks
android/*.keystore
android/app/*.jks
# Go backend build outputs
/go_backend/*.aar
/go_backend/*.jar
/go_backend/*.exe
/go_backend/*.xcframework/
# iOS
ios/Frameworks/
ios/Pods/
ios/.symlinks/
ios/Flutter/Flutter.framework/
ios/Flutter/Flutter.podspec
# Android build state and signing material
/android/.gradle/
/android/.kotlin/
/android/app/build/
/android/app/libs/*.aar
/android/app/libs/*-sources.jar
/android/local.properties
/android/*.iml
/android/key.properties
/android/*.jks
/android/*.keystore
/android/app/*.jks
# Extension folder
extension/*
extension/v2/
extension/v2/**
# iOS generated state
/ios/Frameworks/
/ios/Pods/
/ios/.symlinks/
/ios/Flutter/ephemeral/
/ios/Flutter/Flutter.framework/
/ios/Flutter/Flutter.podspec
*.xcarchive
DerivedData/
# Agent instructions
AGENTS.md
# Credentials and machine-local configuration
.env
.env.*
!.env.example
*.mobileprovision
*.p12
*.pem
# Temp/misc
.tmp/
# Local research and design material
/design/
/referensi/
/extension/
/tool/
/spotiflac_android/
# Documentation published separately. Keep the in-repo extension contract
# available because contribution templates link to it.
/docs/*
!/docs/EXTENSION_DEVELOPMENT.md
# Temporary files and logs
/.tmp/
nul
NUL
network_requests.txt
*.bak
/network_requests.txt
/AndroidManifest.xml
# Log files
*.bak
*.orig
*.swp
*.tmp
*.log
hs_err_*.log
flutter_*.log
# Development tools
tool/
.claude/settings.local.json
.playwright-mcp/
.rtk/
CLAUDE.md
# FVM Version Cache
.fvm/
+13 -13
View File
@@ -1206,8 +1206,8 @@ Thank you for your understanding and continued support. This decision was made t
### Highlights
- **Local Library Scanning** ([#117](https://github.com/zarzet/SpotiFLAC-Mobile/issues/117)): Scan existing music collection to detect duplicates (FLAC, M4A, MP3, Opus, OGG)
- **Duplicate Detection** ([#117](https://github.com/zarzet/SpotiFLAC-Mobile/issues/117)): "In Library" badge on tracks matching by ISRC or track name + artist
- **Local Library Scanning** ([#117](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/117)): Scan existing music collection to detect duplicates (FLAC, M4A, MP3, Opus, OGG)
- **Duplicate Detection** ([#117](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/117)): "In Library" badge on tracks matching by ISRC or track name + artist
- **Unified Library Tab**: History renamed to Library, shows Downloaded + Local Library tracks with source badges
### Added
@@ -1275,7 +1275,7 @@ Same as 3.3.1 but fixes crash issues caused by FFmpeg.
### Added
- **Clear All Queue Button**: Cancel all queued downloads with one tap ([#96](https://github.com/zarzet/SpotiFLAC-Mobile/issues/96))
- **Clear All Queue Button**: Cancel all queued downloads with one tap ([#96](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/96))
- **IDHS Fallback**: Fallback link resolver when SongLink fails (rate limited 8 req/min)
- **Lossy Bitrate Options**: MP3 (320/256/192/128kbps), Opus (128/96/64kbps)
- **Search Filters**: Filter results by type (Tracks, Artists, Albums, Playlists)
@@ -1292,10 +1292,10 @@ Same as 3.3.1 but fixes crash issues caused by FFmpeg.
### Fixed
- **MP3 Download Error 403**: Fixed 403 Forbidden error when downloading MP3 files ([#108](https://github.com/zarzet/SpotiFLAC-Mobile/issues/108))
- **MP3 Download Error 403**: Fixed 403 Forbidden error when downloading MP3 files ([#108](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/108))
- **Opus Cover Art**: Implemented METADATA_BLOCK_PICTURE for proper cover embedding
- **Deezer Pagination**: Fixed >25 tracks only showing first 25 ([#112](https://github.com/zarzet/SpotiFLAC-Mobile/issues/112))
- **Duplicate Embed Lyrics Setting**: Removed from Options page ([#110](https://github.com/zarzet/SpotiFLAC-Mobile/issues/110))
- **Deezer Pagination**: Fixed >25 tracks only showing first 25 ([#112](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/112))
- **Duplicate Embed Lyrics Setting**: Removed from Options page ([#110](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/110))
---
@@ -1508,7 +1508,7 @@ Same as 3.3.1 but fixes crash issues caused by FFmpeg.
- Spanish: Credits 125 ([@credits125](https://crowdin.com/profile/credits125))
- Portuguese: Pedro Marcondes ([@justapedro](https://crowdin.com/profile/justapedro))
- Russian: Владислав ([@odinokiy_kot](https://crowdin.com/profile/odinokiy_kot))
- **Quick Search Provider Switcher** ([#76](https://github.com/zarzet/SpotiFLAC-Mobile/issues/76)): Dropdown menu in search bar for instant provider switching
- **Quick Search Provider Switcher** ([#76](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/76)): Dropdown menu in search bar for instant provider switching
- Tap the search icon to reveal a dropdown menu with all available search providers
- Shows default provider (Deezer based on metadata source setting) at the top
- Lists all enabled extensions with custom search capability
@@ -1517,16 +1517,16 @@ Same as 3.3.1 but fixes crash issues caused by FFmpeg.
- Search hint text updates immediately when switching providers
- Re-triggers search automatically if there's existing text in the search bar
- Eliminates need to navigate to Settings > Extensions > Search Provider
- **Extension Button Setting Type** ([#74](https://github.com/zarzet/SpotiFLAC-Mobile/issues/74)): New setting type for extension actions
- **Extension Button Setting Type** ([#74](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/74)): New setting type for extension actions
- Extensions can define `button` type in manifest settings
- Triggers JavaScript function when tapped (e.g., start OAuth flow)
- Useful for authentication, manual sync, or any custom action
- **Genre & Label Metadata** ([#75](https://github.com/zarzet/SpotiFLAC-Mobile/issues/75)): Downloaded tracks now include genre and record label information
- **Genre & Label Metadata** ([#75](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/75)): Downloaded tracks now include genre and record label information
- Fetches genre and label from Deezer album API for each track
- Embeds GENRE, ORGANIZATION (label), and COPYRIGHT tags into FLAC files
- Works automatically when Deezer track ID is available (via ISRC matching)
- Supports all download services (Tidal, Qobuz, Amazon) and extension downloads
- **MP3 Quality Option** ([#69](https://github.com/zarzet/SpotiFLAC-Mobile/issues/69)): Optional MP3 download format with FLAC-to-MP3 conversion
- **MP3 Quality Option** ([#69](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/69)): Optional MP3 download format with FLAC-to-MP3 conversion
- New "Enable MP3 Option" toggle in Settings > Download > Audio Quality
- When enabled, MP3 (320kbps) appears as a quality option alongside FLAC options
- Available in both the quality picker dialog and default quality settings
@@ -1552,12 +1552,12 @@ Same as 3.3.1 but fixes crash issues caused by FFmpeg.
- **Artist Name in Album Screen**: Album info card now displays artist name below album title
- Extracted from first track's artist metadata
- Styled with `onSurfaceVariant` color for visual hierarchy
- **Disc Separation for Multi-Disc Albums** ([#70](https://github.com/zarzet/SpotiFLAC-Mobile/issues/70)): Downloaded albums with multiple discs now display tracks grouped by disc
- **Disc Separation for Multi-Disc Albums** ([#70](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/70)): Downloaded albums with multiple discs now display tracks grouped by disc
- Visual disc separator header showing "Disc 1", "Disc 2", etc.
- Tracks sorted by disc number first, then by track number
- Single-disc albums display normally without separators
- Fixes confusion when albums have duplicate track numbers across discs
- **Album Grouping in Recents** ([#70](https://github.com/zarzet/SpotiFLAC-Mobile/issues/70)): Downloads now show as albums instead of individual tracks in the Recent section
- **Album Grouping in Recents** ([#70](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues/70)): Downloads now show as albums instead of individual tracks in the Recent section
- Prevents flooding the recents list when downloading full albums
- Groups tracks by album name and artist
- Tapping navigates directly to the downloaded album screen
@@ -1697,4 +1697,4 @@ SpotiFLAC 3.0 introduces a powerful extension system that allows third-party int
---
_For older versions, see [GitHub Releases_](https://github.com/zarzet/SpotiFLAC-Mobile/releases)
_For older versions, see [GitHub Releases_](https://github.com/spotiflacapp/SpotiFLAC-Mobile/releases)
+117 -239
View File
@@ -1,289 +1,167 @@
# Contributing to SpotiFLAC
# Contributing to SpotiFLAC Mobile
First off, thank you for considering contributing to SpotiFLAC! 🎉
Thank you for helping improve SpotiFLAC Mobile. Bug reports, focused pull
requests, documentation, and translations are all welcome.
This document provides guidelines and steps for contributing. Following these guidelines helps maintain code quality and ensures a smooth collaboration process.
Please follow the [Code of Conduct](CODE_OF_CONDUCT.md) when participating in
the project.
## Table of Contents
## Before You Start
- [Code of Conduct](#code-of-conduct)
- [How Can I Contribute?](#how-can-i-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Features](#suggesting-features)
- [Code Contributions](#code-contributions)
- [Translations](#translations)
- [Development Setup](#development-setup)
- [Project Structure](#project-structure)
- [Coding Guidelines](#coding-guidelines)
- [Commit Guidelines](#commit-guidelines)
- [Pull Request Process](#pull-request-process)
- Search the [existing issues](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues)
before opening a new one.
- Use the issue template that best matches the problem.
- Keep pull requests focused. Separate unrelated fixes into separate PRs.
- Never commit credentials, signing files, downloaded media, or generated build
artifacts.
## Code of Conduct
Translations are managed through the
[SpotiFLAC Mobile Crowdin project](https://crowdin.com/project/spotiflac-mobile).
The English source strings live in `lib/l10n/arb/app_en.arb`.
This project and everyone participating in it is governed by our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.
## Toolchain
## How Can I Contribute?
The repository is the source of truth for tool versions:
### Reporting Bugs
- Flutter: `.fvmrc`
- Dart: bundled with the pinned Flutter SDK
- Go: `go_backend/go.mod`
- Android SDK, NDK, and Java: `.github/workflows/ci.yml`
- Xcode: required only for iOS builds
Before creating bug reports, please check the [existing issues](https://github.com/zarzet/SpotiFLAC-Mobile/issues) to avoid duplicates.
When creating a bug report, please use the bug report template and include:
- **Clear and descriptive title**
- **Steps to reproduce** the issue
- **Expected behavior** vs **actual behavior**
- **Screenshots or screen recordings** if applicable
- **Device information** (model, OS version)
- **App version**
- **Logs** from Settings > About > View Logs
### Suggesting Features
Feature requests are welcome! Please use the feature request template and:
- **Check existing issues** to avoid duplicates
- **Describe the feature** clearly
- **Explain the use case** - why would this be useful?
- **Consider the scope** - is this a small enhancement or a major feature?
### Code Contributions
1. **Fork the repository** and create your branch from `main`
2. **Make your changes** following our coding guidelines
3. **Test your changes** thoroughly
4. **Submit a pull request** to the `main` branch
### Translations
We use [Crowdin](https://crowdin.com/project/spotiflac-mobile) for translations. To contribute:
1. Visit our [Crowdin project](https://crowdin.com/project/spotiflac-mobile)
2. Select your language or request a new one
3. Start translating!
Translation files are located in `lib/l10n/arb/`.
[FVM](https://fvm.app/) is recommended. If you do not use FVM, install the
exact Flutter version declared in `.fvmrc` and replace `fvm flutter` with
`flutter` (and `fvm dart` with `dart`) in the commands below.
## Development Setup
### Prerequisites
1. Fork and clone the repository:
- **Flutter SDK** 3.10.0 or higher
- **Dart SDK** 3.10.0 or higher
- **Android Studio** or **VS Code** with Flutter extensions
- **Git**
### Getting Started
1. **Clone your fork**
```bash
git clone https://github.com/YOUR_USERNAME/SpotiFLAC-Mobile.git
cd SpotiFLAC-Mobile
```
2. **Add upstream remote**
```bash
git remote add upstream https://github.com/spotiflacapp/SpotiFLAC-Mobile.git
```
3. **Use FVM (Flutter Version: 3.41.5)**
2. Install the pinned Flutter SDK and Dart dependencies:
```bash
fvm use
fvm install
fvm flutter pub get
```
4. **Install dependencies**
```bash
flutter pub get
```
5. **Generate code** (for Riverpod, JSON serialization, etc.)
```bash
dart run build_runner build --delete-conflicting-outputs
```
6. **Set up Go environment (Go Version: 1.25.9)**
Building the Go backend for Android requires the **Android NDK** (r29 is what CI uses). Make sure `ANDROID_NDK_HOME` points to it and `CGO_ENABLED=1`.
3. Build the Go backend for Android. `ANDROID_NDK_HOME` must point to the NDK
version used by CI and `CGO_ENABLED` must be enabled.
```bash
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
cd go_backend
go mod download
go install golang.org/x/mobile/cmd/gomobile
gomobile init
mkdir -p ../android/app/libs
gomobile bind -target=android -androidapi 24 -o ../android/app/libs/gobackend.aar .
gomobile bind \
-target=android/arm,android/arm64 \
-androidapi 24 \
-o ../android/app/libs/gobackend.aar \
.
cd ..
```
7. **Run the app**
Running `go install` from `go_backend/` uses the `x/mobile` version pinned by
`go.mod`. Do not replace it with `@latest` in project scripts.
4. Run the app:
```bash
flutter run
fvm flutter run
```
### Building
For iOS, run `scripts/build_ios.sh` on macOS before opening
`ios/Runner.xcworkspace`.
## Project Boundaries
```text
lib/ Flutter UI, state, models, and platform orchestration
go_backend/ Download pipeline, extension runtime, and shared backend logic
android/ Android platform bridge and foreground worker
ios/ iOS platform bridge and application project
test/ Flutter unit and widget tests
assets/ Images, fonts, and bundled resources
docs/ Contributor-facing technical contracts
scripts/ Reproducible project build helpers
```
SpotiFLAC Mobile is extension-driven. Extension-specific behavior must be
declared through a generic manifest field, capability, or reusable app API.
Do not add provider-name checks such as `if source == 'provider-name'` to the
main app. The Go backend should parse and expose the generic declaration, and
Dart should consume that declaration without knowing which extension uses it.
## Generated Files
- After changing ARB files, run `fvm flutter gen-l10n` and commit the resulting
localization sources.
- Run `fvm dart run build_runner build --delete-conflicting-outputs` only when a
model or generator input changes, then commit the relevant generated source.
- Do not commit `build/`, `.dart_tool/`, AAR/XCFramework output, IDE state, or
local research directories.
## Validation
Run checks that cover the code you changed. Before opening a PR, the relevant
commands should pass.
Flutter and Dart:
```bash
# Debug build
flutter build apk --debug
# Release build
flutter build apk --release
fvm dart format --output=none --set-exit-if-changed lib test
fvm flutter analyze
fvm flutter test
```
## Project Structure
```
lib/
├── l10n/ # Localization files
│ └── arb/ # ARB translation files
├── models/ # Data models
├── providers/ # Riverpod providers
├── screens/ # UI screens
│ └── settings/ # Settings sub-screens
├── services/ # Business logic services
├── theme/ # App theming
├── utils/ # Utility functions
├── widgets/ # Reusable widgets
├── app.dart # App configuration
└── main.dart # Entry point
```
## Coding Guidelines
### General
- Follow [Effective Dart](https://dart.dev/effective-dart) guidelines
- Use meaningful variable and function names
- Keep functions small and focused
- Add comments for complex logic
### Formatting
- Use `dart format` before committing
- Maximum line length: 80 characters
- Use trailing commas for better formatting
Go backend:
```bash
dart format .
cd go_backend
gofmt -w .
go vet ./...
go test ./...
```
### Linting
Ensure your code passes all lints:
Android native code, after building `gobackend.aar`:
```bash
flutter analyze
cd android
./gradlew :app:compileDebugKotlin :app:testDebugUnitTest
```
### State Management
For user-facing changes, add or update tests where practical and include
before/after screenshots for UI changes.
We use **Riverpod** for state management, with hand-written `Notifier`s
(no `riverpod_annotation` code generation). Follow this pattern:
## Code and Commit Style
```dart
class MyNotifier extends Notifier<MyState> {
@override
MyState build() => MyState();
- Follow `analysis_options.yaml`, `.editorconfig`, and existing module patterns.
- Keep user-facing strings in the localization files.
- Prefer small functions and explicit error handling at platform boundaries.
- Use [Conventional Commits](https://www.conventionalcommits.org/), for example:
// Methods to update state
}
```text
feat(download): add batch selection
fix(storage): handle revoked folder access
docs(contributing): refresh Android setup
```
final myProvider = NotifierProvider<MyNotifier, MyState>(MyNotifier.new);
```
## Pull Requests
### Localization
1. Create a branch from an up-to-date `main`.
2. Make one focused change and include tests or verification evidence.
3. Complete the pull request template, including any checks that were not run
and why.
4. Link related issues with `Fixes #123` where appropriate.
5. Respond to review feedback with follow-up commits; maintainers may squash
commits when merging.
All user-facing strings should be localized:
```dart
// Good
Text(AppLocalizations.of(context)!.downloadComplete)
// Bad
Text('Download Complete')
```
To add new strings:
1. Add the key to `lib/l10n/arb/app_en.arb`
2. Run `flutter gen-l10n`
## Commit Guidelines
We follow [Conventional Commits](https://www.conventionalcommits.org/):
```
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
```
### Types
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code style changes (formatting, etc.)
- `refactor`: Code refactoring
- `perf`: Performance improvements
- `test`: Adding or updating tests
- `chore`: Maintenance tasks
### Examples
```
feat(download): add batch download support
fix(ui): resolve overflow on small screens
docs: update contributing guidelines
chore(deps): update flutter_riverpod to 3.1.0
```
## Pull Request Process
1. **Update your fork**
```bash
git fetch upstream
git rebase upstream/main
```
2. **Create a feature branch**
```bash
git checkout -b feat/my-new-feature
```
3. **Make your changes** and commit following our guidelines
4. **Push to your fork**
```bash
git push origin feat/my-new-feature
```
5. **Create a Pull Request**
- Target the `main` branch
- Fill in the PR template
- Link related issues
6. **Address review feedback**
- Make requested changes
- Push additional commits
- Request re-review when ready
### PR Requirements
- [ ] Code follows project conventions
- [ ] All tests pass
- [ ] No new linting errors
- [ ] Documentation updated (if needed)
- [ ] Commit messages follow guidelines
- [ ] PR description is clear and complete
CI runs `flutter analyze`, `flutter test`, `go vet`, and `go test` on every pull request — make sure they pass locally before pushing.
## Questions?
If you have questions, feel free to:
- Open a [Discussion](https://github.com/spotiflacapp/SpotiFLAC-Mobile/discussions)
- Check existing [Issues](https://github.com/spotiflacapp/SpotiFLAC-Mobile/issues)
Thank you for contributing! 💚
When reporting a crash, include the SpotiFLAC Mobile version, release channel,
device/OS, exact reproduction steps, storage mode, and exported app logs. For a
cold-start Android crash, `adb logcat -b crash -d` is especially useful.
+27 -10
View File
@@ -16,8 +16,7 @@
<div align="center">
[![GitHub Release](https://img.shields.io/github/v/release/zarzet/SpotiFLAC-Mobile?style=for-the-badge&logo=github)](https://github.com/zarzet/SpotiFLAC-Mobile/releases)
[![VirusTotal](https://img.shields.io/badge/VirusTotal-Safe-brightgreen?style=for-the-badge&logo=virustotal)](https://www.virustotal.com/gui/file/31d1bf3c3b2015c13e83c4f909a7c6093a9423e3e702f0c582a3e0035c849424)
[![GitHub Release](https://img.shields.io/github/v/release/spotiflacapp/SpotiFLAC-Mobile?style=for-the-badge&logo=github)](https://github.com/spotiflacapp/SpotiFLAC-Mobile/releases)
[![Crowdin](https://img.shields.io/badge/HELP%20TRANSLATE%20ON-CROWDIN-%2321252b?style=for-the-badge&logo=crowdin)](https://crowdin.com/project/spotiflac-mobile)
[![Telegram Channel](https://img.shields.io/badge/CHANNEL-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/spotiflac)
@@ -59,6 +58,18 @@ Extensions let the community add new music sources and features without waiting
---
## Development
SpotiFLAC Mobile combines a Flutter/Dart UI, a Go backend compiled with
`gomobile`, and thin Android/iOS platform bridges. Toolchain versions are
pinned in [`.fvmrc`](.fvmrc), [`go_backend/go.mod`](go_backend/go.mod), and the
GitHub Actions workflows.
Start with the [Contributing Guide](CONTRIBUTING.md) for the development setup,
project boundaries, validation commands, and pull request checklist.
---
## Related Projects
### [SpotiFLAC (Desktop)](https://github.com/afkarxyz/SpotiFLAC)
@@ -75,7 +86,10 @@ Python library for SpotiFLAC integration, maintained by [@ShuShuzinhuu](https://
<summary><b>Why does the Store tab ask me to enter a URL?</b></summary>
<br>
Starting from version 3.8.0, SpotiFLAC uses a decentralized extension repository system extensions are hosted on GitHub repositories rather than a built-in server, so anyone can create and host their own. Enter a repository URL in the Store tab to browse and install extensions.
Starting from version 3.8.0, SpotiFLAC Mobile uses a decentralized extension
repository system. Extensions are hosted independently rather than on a
built-in server, so anyone can create and host a compatible repository. Enter
a repository URL in the Store tab to browse and install extensions.
</details>
@@ -107,7 +121,9 @@ Yes! Just paste the playlist URL in the search bar. The app will fetch all track
<summary><b>Why do I need to grant storage permission?</b></summary>
<br>
The app needs permission to save downloaded files to your device. On Android 13+, you may need to grant **All files access** under **Settings > Apps > SpotiFLAC > Permissions**.
The app needs a writable destination for downloaded files. On Android, choose a
folder with the system folder picker (SAF), or use the app-specific folder. If
Android revokes a saved folder grant, select the folder again in Settings.
</details>
@@ -115,7 +131,8 @@ The app needs permission to save downloaded files to your device. On Android 13+
<summary><b>Is this app safe?</b></summary>
<br>
Yes SpotiFLAC is open source and you can verify the code yourself. Each release is also scanned with VirusTotal (see badge above).
SpotiFLAC Mobile is open source, so its code and build workflows can be
inspected directly in this repository.
</details>
@@ -128,13 +145,13 @@ Some countries have restricted access to certain streaming service APIs. If down
</details>
<details>
<summary><b>Can I add SpotiFLAC to AltStore or SideStore?</b></summary>
<summary><b>Can I add SpotiFLAC Mobile to AltStore or SideStore?</b></summary>
<br>
Yes! Add the official source to receive updates directly within the app. Copy this link:
```
https://raw.githubusercontent.com/zarzet/SpotiFLAC-Mobile/refs/heads/main/apps.json
https://raw.githubusercontent.com/spotiflacapp/SpotiFLAC-Mobile/refs/heads/main/apps.json
```
In AltStore/SideStore, go to **Browse > Sources**, tap **+**, and paste the link.
@@ -142,7 +159,7 @@ In AltStore/SideStore, go to **Browse > Sources**, tap **+**, and paste the link
</details>
> [!NOTE]
> If SpotiFLAC is useful to you, consider supporting development:
> If SpotiFLAC Mobile is useful to you, consider supporting development:
>
> [![Ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/zarzet)
@@ -152,8 +169,8 @@ In AltStore/SideStore, go to **Browse > Sources**, tap **+**, and paste the link
Thanks to everyone who has contributed to SpotiFLAC Mobile!
<a href="https://github.com/zarzet/SpotiFLAC-Mobile/graphs/contributors">
<img src="https://contrib.rocks/image?repo=zarzet/SpotiFLAC-Mobile" />
<a href="https://github.com/spotiflacapp/SpotiFLAC-Mobile/graphs/contributors">
<img src="https://contrib.rocks/image?repo=spotiflacapp/SpotiFLAC-Mobile" />
</a>
We also appreciate everyone who helped with [translations on Crowdin](https://crowdin.com/project/spotiflac-mobile), reported bugs, suggested features, and spread the word.
+3 -3
View File
@@ -9,9 +9,9 @@
"developerName": "zarzet",
"version": "4.7.1",
"versionDate": "2026-07-01",
"downloadURL": "https://github.com/zarzet/SpotiFLAC-Mobile/releases/download/v4.7.1/SpotiFLAC-v4.7.1-ios-unsigned.ipa",
"localizedDescription": "SpotiFLAC Mobile is written in Flutter. Download tracks in true FLAC via installable extensions for Tidal, Qobuz, Deezer, and more.",
"iconURL": "https://raw.githubusercontent.com/zarzet/SpotiFLAC-Mobile/main/assets/images/logo.png",
"downloadURL": "https://github.com/spotiflacapp/SpotiFLAC-Mobile/releases/download/v4.7.1/SpotiFLAC-v4.7.1-ios-unsigned.ipa",
"localizedDescription": "SpotiFLAC Mobile is written in Flutter and uses installable extensions for metadata and audio downloads.",
"iconURL": "https://raw.githubusercontent.com/spotiflacapp/SpotiFLAC-Mobile/main/assets/images/logo.png",
"size": 37455821
}
]
+2 -2
View File
@@ -5,7 +5,7 @@
# Template for the changelog body
body = """
{%- macro remote_url() -%}
https://github.com/zarzet/SpotiFLAC-Mobile
https://github.com/spotiflacapp/SpotiFLAC-Mobile
{%- endmacro -%}
{% if version %}\
@@ -99,5 +99,5 @@ tag_pattern = "v[0-9].*"
sort_commits = "newest"
[remote.github]
owner = "zarzet"
owner = "spotiflacapp"
repo = "SpotiFLAC-Mobile"
+1 -1
View File
@@ -1,4 +1,4 @@
arb-dir: lib/l10n/arb
arb-dir: lib/l10n/arb
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations
+1 -1
View File
@@ -13,7 +13,7 @@ class AppInfo {
static const String mobileAuthor = 'zarzet';
static const String originalAuthor = 'afkarxyz';
static const String githubRepo = 'zarzet/SpotiFLAC-Mobile';
static const String githubRepo = 'spotiflacapp/SpotiFLAC-Mobile';
static const String githubUrl = 'https://github.com/$githubRepo';
static const String originalGithubUrl =
'https://github.com/afkarxyz/SpotiFLAC';
+1 -1
View File
@@ -1,5 +1,5 @@
name: spotiflac_android
description: Download Spotify tracks in FLAC using extension providers
description: Extension-driven music metadata and downloads for mobile devices
publish_to: "none"
version: 4.8.1+139
+26 -59
View File
@@ -1,78 +1,45 @@
#!/bin/bash
# Build script for iOS XCFramework
# This script compiles the Go backend to XCFramework for iOS
# Must be run on macOS with Xcode installed
#!/usr/bin/env bash
# Build the Go backend XCFramework used by SpotiFLAC Mobile on iOS.
set -e
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
GO_BACKEND_DIR="$PROJECT_DIR/go_backend"
IOS_DIR="$PROJECT_DIR/ios"
OUTPUT_DIR="$IOS_DIR/Frameworks"
OUTPUT_DIR="$PROJECT_DIR/ios/Frameworks"
echo "=== SpotiFLAC iOS Build Script ==="
echo "Project directory: $PROJECT_DIR"
echo "Go backend directory: $GO_BACKEND_DIR"
echo "Output directory: $OUTPUT_DIR"
echo "SpotiFLAC Mobile iOS backend build"
echo "Project: $PROJECT_DIR"
echo "Output: $OUTPUT_DIR"
# Check if running on macOS
if [[ "$(uname)" != "Darwin" ]]; then
echo "Error: This script must be run on macOS"
exit 1
echo "Error: this script must run on macOS with Xcode installed." >&2
exit 1
fi
# Check if Go is installed
if ! command -v go &> /dev/null; then
echo "Error: Go is not installed. Please install Go first."
exit 1
if ! command -v go >/dev/null 2>&1; then
echo "Error: Go is not installed." >&2
exit 1
fi
echo "Go version: $(go version)"
cd "$GO_BACKEND_DIR"
go mod download
# Check if gomobile is installed
if ! command -v gomobile &> /dev/null; then
echo "Installing gomobile..."
go install golang.org/x/mobile/cmd/gomobile@latest
go install golang.org/x/mobile/cmd/gobind@latest
fi
# Initialize gomobile (required for iOS builds)
echo "Initializing gomobile..."
# Running inside the module installs the x/mobile revision pinned by go.mod.
go install golang.org/x/mobile/cmd/gomobile
export PATH="$(go env GOPATH)/bin:$PATH"
gomobile init
# Create output directory
mkdir -p "$OUTPUT_DIR"
gomobile bind \
-target=ios \
-tags ios \
-o "$OUTPUT_DIR/Gobackend.xcframework" \
.
# Navigate to Go backend directory
cd "$GO_BACKEND_DIR"
# Download dependencies
echo "Downloading Go dependencies..."
go mod download
go mod tidy
# Build XCFramework for iOS
echo "Building XCFramework for iOS..."
gomobile bind -target=ios -o "$OUTPUT_DIR/Gobackend.xcframework" .
# Verify output
if [ -d "$OUTPUT_DIR/Gobackend.xcframework" ]; then
echo "✅ Successfully built Gobackend.xcframework"
echo "Output: $OUTPUT_DIR/Gobackend.xcframework"
# List architectures
echo ""
echo "Architectures included:"
ls -la "$OUTPUT_DIR/Gobackend.xcframework/"
else
echo "❌ Failed to build XCFramework"
exit 1
if [[ ! -d "$OUTPUT_DIR/Gobackend.xcframework" ]]; then
echo "Error: Gobackend.xcframework was not created." >&2
exit 1
fi
echo ""
echo "=== Build Complete ==="
echo "Next steps:"
echo "1. Open ios/Runner.xcworkspace in Xcode"
echo "2. Add Gobackend.xcframework to the project"
echo "3. Build and run the app"
echo "Built $OUTPUT_DIR/Gobackend.xcframework"