From 5c579cf7c3dd4c656592b83d08e9e43c78f41623 Mon Sep 17 00:00:00 2001 From: Arvin Date: Sat, 16 May 2026 21:28:33 +0200 Subject: [PATCH] Add iOS TestFlight scaffold --- .github/workflows/ios-testflight.yml | 105 ++++++++++++++++ docs/ios-testflight.md | 28 +++++ iosApp/ARVIO/ARVIOApp.swift | 11 ++ .../AppIcon.appiconset/Contents.json | 26 ++++ .../AppIcon.appiconset/Icon-1024.png | Bin 0 -> 79846 bytes .../AppIcon.appiconset/Icon-20@2x.png | Bin 0 -> 1193 bytes .../AppIcon.appiconset/Icon-20@3x.png | Bin 0 -> 1651 bytes .../AppIcon.appiconset/Icon-29@2x.png | Bin 0 -> 1592 bytes .../AppIcon.appiconset/Icon-29@3x.png | Bin 0 -> 2299 bytes .../AppIcon.appiconset/Icon-40@2x.png | Bin 0 -> 1968 bytes .../AppIcon.appiconset/Icon-40@3x.png | Bin 0 -> 3145 bytes .../AppIcon.appiconset/Icon-60@2x.png | Bin 0 -> 3145 bytes .../AppIcon.appiconset/Icon-60@3x.png | Bin 0 -> 5069 bytes .../AppIcon.appiconset/Icon-iPad-20.png | Bin 0 -> 676 bytes .../AppIcon.appiconset/Icon-iPad-20@2x.png | Bin 0 -> 1193 bytes .../AppIcon.appiconset/Icon-iPad-29.png | Bin 0 -> 918 bytes .../AppIcon.appiconset/Icon-iPad-29@2x.png | Bin 0 -> 1592 bytes .../AppIcon.appiconset/Icon-iPad-40.png | Bin 0 -> 1193 bytes .../AppIcon.appiconset/Icon-iPad-40@2x.png | Bin 0 -> 1968 bytes .../AppIcon.appiconset/Icon-iPad-76.png | Bin 0 -> 2011 bytes .../AppIcon.appiconset/Icon-iPad-76@2x.png | Bin 0 -> 4223 bytes .../AppIcon.appiconset/Icon-iPad-83.5@2x.png | Bin 0 -> 4722 bytes iosApp/ARVIO/Assets.xcassets/Contents.json | 6 + iosApp/ARVIO/Components.swift | 83 +++++++++++++ iosApp/ARVIO/HomeView.swift | 101 +++++++++++++++ iosApp/ARVIO/Info.plist | 42 +++++++ iosApp/ARVIO/Models.swift | 31 +++++ iosApp/ARVIO/RootView.swift | 115 ++++++++++++++++++ iosApp/ARVIO/SearchView.swift | 25 ++++ iosApp/ARVIO/SettingsView.swift | 39 ++++++ iosApp/ARVIO/Theme.swift | 23 ++++ iosApp/ARVIO/WatchlistView.swift | 11 ++ iosApp/project.yml | 28 +++++ 33 files changed, 674 insertions(+) create mode 100644 .github/workflows/ios-testflight.yml create mode 100644 docs/ios-testflight.md create mode 100644 iosApp/ARVIO/ARVIOApp.swift create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-1024.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-20@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-29@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-29@3x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-20.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-20@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-29.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-29@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-40.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-40@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-76.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-76@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-83.5@2x.png create mode 100644 iosApp/ARVIO/Assets.xcassets/Contents.json create mode 100644 iosApp/ARVIO/Components.swift create mode 100644 iosApp/ARVIO/HomeView.swift create mode 100644 iosApp/ARVIO/Info.plist create mode 100644 iosApp/ARVIO/Models.swift create mode 100644 iosApp/ARVIO/RootView.swift create mode 100644 iosApp/ARVIO/SearchView.swift create mode 100644 iosApp/ARVIO/SettingsView.swift create mode 100644 iosApp/ARVIO/Theme.swift create mode 100644 iosApp/ARVIO/WatchlistView.swift create mode 100644 iosApp/project.yml diff --git a/.github/workflows/ios-testflight.yml b/.github/workflows/ios-testflight.yml new file mode 100644 index 000000000..45b81acdf --- /dev/null +++ b/.github/workflows/ios-testflight.yml @@ -0,0 +1,105 @@ +name: iOS TestFlight + +on: + workflow_dispatch: + +jobs: + testflight: + name: Build and Upload iOS + runs-on: macos-15 + timeout-minutes: 60 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Select Xcode + run: sudo xcode-select -s /Applications/Xcode.app + + - name: Install XcodeGen + run: brew install xcodegen + + - name: Write App Store Connect key + env: + APP_STORE_CONNECT_PRIVATE_KEY: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY }} + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + run: | + mkdir -p "$RUNNER_TEMP/private_keys" + printf '%s' "$APP_STORE_CONNECT_PRIVATE_KEY" > "$RUNNER_TEMP/private_keys/AuthKey_${APP_STORE_CONNECT_KEY_ID}.p8" + + - name: Generate Xcode project + run: xcodegen generate --spec iosApp/project.yml --project iosApp + + - name: Archive + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + xcodebuild \ + -project iosApp/ARVIO.xcodeproj \ + -scheme ARVIO \ + -configuration Release \ + -destination "generic/platform=iOS" \ + -archivePath "$RUNNER_TEMP/ARVIO.xcarchive" \ + DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \ + CURRENT_PROJECT_VERSION="$GITHUB_RUN_NUMBER" \ + CODE_SIGN_STYLE=Automatic \ + -allowProvisioningUpdates \ + -authenticationKeyPath "$RUNNER_TEMP/private_keys/AuthKey_${APP_STORE_CONNECT_KEY_ID}.p8" \ + -authenticationKeyID "$APP_STORE_CONNECT_KEY_ID" \ + -authenticationKeyIssuerID "$APP_STORE_CONNECT_ISSUER_ID" \ + clean archive + + - name: Export IPA + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + cat > "$RUNNER_TEMP/ExportOptions.plist" < + + + + method + app-store + teamID + ${APPLE_TEAM_ID} + signingStyle + automatic + uploadSymbols + + + + PLIST + + xcodebuild \ + -exportArchive \ + -archivePath "$RUNNER_TEMP/ARVIO.xcarchive" \ + -exportPath "$RUNNER_TEMP/export" \ + -exportOptionsPlist "$RUNNER_TEMP/ExportOptions.plist" \ + -allowProvisioningUpdates \ + -authenticationKeyPath "$RUNNER_TEMP/private_keys/AuthKey_${APP_STORE_CONNECT_KEY_ID}.p8" \ + -authenticationKeyID "$APP_STORE_CONNECT_KEY_ID" \ + -authenticationKeyIssuerID "$APP_STORE_CONNECT_ISSUER_ID" + + - name: Upload to TestFlight + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + run: | + xcrun altool \ + --upload-app \ + --type ios \ + --file "$RUNNER_TEMP/export/ARVIO.ipa" \ + --apiKey "$APP_STORE_CONNECT_KEY_ID" \ + --apiIssuer "$APP_STORE_CONNECT_ISSUER_ID" + + - name: Upload IPA artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: ARVIO-iOS-IPA + path: ${{ runner.temp }}/export/*.ipa + if-no-files-found: ignore diff --git a/docs/ios-testflight.md b/docs/ios-testflight.md new file mode 100644 index 000000000..f4167aadf --- /dev/null +++ b/docs/ios-testflight.md @@ -0,0 +1,28 @@ +# iOS TestFlight + +This repo contains an additive iOS SwiftUI shell under `iosApp/`. + +The Android TV APK remains in `app/` and is not coupled to the iOS target. + +## Required GitHub Actions secrets + +- `APP_STORE_CONNECT_KEY_ID` +- `APP_STORE_CONNECT_ISSUER_ID` +- `APP_STORE_CONNECT_PRIVATE_KEY` +- `APPLE_TEAM_ID` +- `IOS_BUNDLE_ID` + +The current workflow uses GitHub's macOS runner and Xcode automatic signing with the App Store Connect API key. +If Apple refuses automatic signing in CI, the workflow will need manual distribution certificate and provisioning profile secrets. + +## Running + +Use **Actions > iOS TestFlight > Run workflow**. + +The workflow: + +1. Installs XcodeGen. +2. Generates `iosApp/ARVIO.xcodeproj`. +3. Archives the app with automatic signing. +4. Exports an App Store IPA. +5. Uploads the IPA to TestFlight. diff --git a/iosApp/ARVIO/ARVIOApp.swift b/iosApp/ARVIO/ARVIOApp.swift new file mode 100644 index 000000000..72b727c13 --- /dev/null +++ b/iosApp/ARVIO/ARVIOApp.swift @@ -0,0 +1,11 @@ +import SwiftUI + +@main +struct ARVIOApp: App { + var body: some Scene { + WindowGroup { + RootView() + .preferredColorScheme(.dark) + } + } +} diff --git a/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Contents.json b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..3f705d0d2 --- /dev/null +++ b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,26 @@ +{ + "images": [ + { "filename": "Icon-20@2x.png", "idiom": "iphone", "scale": "2x", "size": "20x20" }, + { "filename": "Icon-20@3x.png", "idiom": "iphone", "scale": "3x", "size": "20x20" }, + { "filename": "Icon-29@2x.png", "idiom": "iphone", "scale": "2x", "size": "29x29" }, + { "filename": "Icon-29@3x.png", "idiom": "iphone", "scale": "3x", "size": "29x29" }, + { "filename": "Icon-40@2x.png", "idiom": "iphone", "scale": "2x", "size": "40x40" }, + { "filename": "Icon-40@3x.png", "idiom": "iphone", "scale": "3x", "size": "40x40" }, + { "filename": "Icon-60@2x.png", "idiom": "iphone", "scale": "2x", "size": "60x60" }, + { "filename": "Icon-60@3x.png", "idiom": "iphone", "scale": "3x", "size": "60x60" }, + { "filename": "Icon-iPad-20.png", "idiom": "ipad", "scale": "1x", "size": "20x20" }, + { "filename": "Icon-iPad-20@2x.png", "idiom": "ipad", "scale": "2x", "size": "20x20" }, + { "filename": "Icon-iPad-29.png", "idiom": "ipad", "scale": "1x", "size": "29x29" }, + { "filename": "Icon-iPad-29@2x.png", "idiom": "ipad", "scale": "2x", "size": "29x29" }, + { "filename": "Icon-iPad-40.png", "idiom": "ipad", "scale": "1x", "size": "40x40" }, + { "filename": "Icon-iPad-40@2x.png", "idiom": "ipad", "scale": "2x", "size": "40x40" }, + { "filename": "Icon-iPad-76.png", "idiom": "ipad", "scale": "1x", "size": "76x76" }, + { "filename": "Icon-iPad-76@2x.png", "idiom": "ipad", "scale": "2x", "size": "76x76" }, + { "filename": "Icon-iPad-83.5@2x.png", "idiom": "ipad", "scale": "2x", "size": "83.5x83.5" }, + { "filename": "Icon-1024.png", "idiom": "ios-marketing", "scale": "1x", "size": "1024x1024" } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-1024.png b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..fffd581482df83475597805012b89da444624a0c GIT binary patch literal 79846 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 VS`bukKRN&a002ovPDHLkV1iRvO{V|= literal 0 HcmV?d00001 diff --git a/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c6bde252f2bacd08a6353a195428afd13702daca GIT binary patch literal 1968 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 literal 0 HcmV?d00001 diff --git a/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8c80d470539389e91e10eded07319a983ab33999 GIT binary patch literal 3145 zcmXX|dmz*68{dWzvso^UA?3JjHJ3=N3o0FvV2{ z3??&XbIj5y+IwL%2Eg~J@k2I?8Vys622=e!t1sI0`wnI8>8J|Boi(z%Q!~?j?oOn6 zcevDz=C0!;4aN;C4Y}Le_E-O2$EN2{a<+eX!szw;kf|U=|HUHrT+S`B_O8MipBG)8 zX162bFS`=khWj{UJI6n=R@WAG=Eqd8-@eTIvBu&B=NtIOfhceJ8v(y&D#zb(-sF;wfwD$HwXMP0U@<;y-GHovPr@38*Zu)?lJY!VP`)pQtl>Kep zyROz*+_uS6M$5Und#>C(W>#;cBh#Vy>Q?KVy|3e=n;FnKcdQ?4IN@?8X3?gomq0`k z8F{Z!>?~;IurRrs$|Q>S?GJVd_Js_jEuW_05nGx#Q7B(nwO62MGXmmpbR){%sZVsQ zuAt96_~-PH2uZIC``gNiSuQEm<)d8ZK=+vAXP^NF+zm;6P=U%U*P*}-1bz5maY$+| z;tZlXP=dZ)B*=q;lkC*lX=MQ)m7P!)B9sFNBF>j2S(F)))eg+;a$pe=c9y4%NHc#n z#vV{8We@@n3lz^tA1w%{NE=8v!zl@0hAh;+FI6Bxb0d8J;h;e9%r1uzp^ak{bWw7iLvqEB>2PLte+FB7*@*ZZ4HU))y?iyxc4P6&hx zibc%-l#|*ByJyw$$fyG?KuGN$I&ZP1O`z~Z_-}i!u57%#VGcHm6~DWR%6$a((6K?G zKwH&9G%USqfph)a`wZ%!adTdV&mK6-B0bU8d~7NaU-|0R=!ebNRS*9|<)aP`xT@UO za;~a4y7rE2vBfn(${)(rc=x4*6~XJCxj*t$N*TQKtaHh>lGX)nt+I%L-5QUX{e!-* z^i>U>RjNPNxj2Q;d25%K8@ZJ^gzL8UE~-nP1Stcv0j5tLq0F<~sQ!8KoQ2AxOETZM z&yn@hjB|{;onqDn?Gs~&hE0#>^HKmci80q1==CAaBYUmCQ67^~EW4F>gyar*)W*aH zJ$6X80xgz47SogR*YBT8I=#6W3Ln&6kz6CtQltW2E3l6|T7KyuwfBlAq5D8pgK8Ng z@x4cQ3SPp^jDiM>kesE;^wDktUR=r3;e^M*Ahy$$e9jFkP4~_XLFfImN@6Zb+2L$~ zq|Z`5iI-P?vAY4x7)~PTtLXQ&HK^o_I6NRzu+(WND`=R8F;lO|)BHT!y+B#5$|d=V z{$kSK9Xh}UzZh12-IgPsqGRwluuh^2)nBmi;PW+G6XAk>zXS*7c8JoeLq8AJ)Vf4o zCsuTiIT4hV!y-#Cmxv{wS5$G%ejt`VJE<*`WBeVIB`vHKEljU2YGa&uZRh*77jeLT zjGHWUo#!f?g~yqrB5C3i)2#Mcz6Y6w{??-!`i$FwNm(B)-O-2 z6Kh*}#8JW}8C&$oAb9P`Z3AvD_%LncIS`TN0|m0DyWefQXadf>D3i}^{o_K)e}P-9ni#F2N*2a^vnTBm8Pn`VqM@FXIA>@vqoCZx$w{j?#;6<<)2X-Ta;C|FUCQLBH?UFF`?Ov+Mb+9_WsmH zf1mbr<>=w)$&%EJrW7<=jx-aLEZH#ZrOBgDD+PH5*&i@^b*JIHaeVy`Uq3~+iWWUO zQI@U2$>l#BEoTG1C71=xG5hte)J>sLUx?0*jGHhbs{_8Y%y;Eot;V}~-z?aEZd`sp zc+e?jE&bO@PQ>-99QIjhHUbQ%Dguu1oK>EWdH1#L3oEo8?EQZdpbFQbgp%ia7SzAY zD(254voftlir$4Jzl?g+nhYJ0Uwfs_FW@Qgl~0(weR$YgqNviTgA?z*?a5(}gQN(P zI}_t-nL#^~-qh9K+x*DZ2*$YuKtH=q+B&f;VBkggRhpPgC-9&c(Yf>TKQn7hKf>5J z7YU&uRSe1sp$4GELdOI^-%m?;qH{WEF&ZB;EUQGEUavR_O1bT&gld{g*1sl_(b06h z!p*9-q<1MLD{<;>;rX&fWh`=C_jaUL4 ztYx@xuOi@D(Oh;4OF^+LG8?thQUPK#Uz4}lQYD6|)MX^cIR|mvhO7RD*D(~j6`Dv$0al-Sa0unnp0 z_gj=xf!W(gYK07|Mcly?0*8xw)BwOtR1pjceYD8vFTQ?n%$0IQEB%A-8u}hvXdPTt z3+=V~QEv6XMq~|lL7TesFUi;e>>)-?=IfDH&kBXu7_aPv+)0qRyBx=@2340U+b2%@ z6wk-rz3JQfeRtd8!Fh|3<8yYdTI{ceX6FhwTVlmkG&xe-PvF}>IzJ*eN36-i+8*)a zZ<*#8v%XRcMVf049g`IbzVX!Kjai3?qVlT>Kla2f1_s>n#BD2&qrkbb(CuqL(V5GP z`B?lZZrnBOtSG%0!mWH`-o$-#DCYQ|U=hl{>jhMmSVgKXA3a{b#@S;z^-$V)s8Bcj zOVJUbp-5Gos{&e5btv;89h}-8sga!o)YA*@hWF+OC#Hh(F6t%bk6*C4to9-8uH8Q$ zQMk^C!vccYZxwnGjV57wCyX|5Tz#*NJ_UV1 z9`5Ln&cb7W_#$j-a81zwgxJtn7C3D|aS!3l)NQ^GiIv43Sfgvy*=8M$~GYl>nUktDw-Knk-`wITn+ zr7kFRl&O+XgS#tDl8p?O15sTySpRFIDN4G=*kepQk%VxOfv(U1tq&iKd)9(pS;TTY zn0OgZqd!KhJjr(B{Yt=cKzZH;|CEUNhZ2HQ;-=#4{UpiyMr27%W@G!#ZkN4+6v=Ef z%OO3@R>eCQo|ay7UOBiPdb!$+gJ?SM>#YhO;hHK0h*9h4{4>XU=5f7pht5t!q1Ia?o1J9`6_d=LP`|K z0zNKl;=G#a&lPp39@(lY1`^N`+EqLU(E*qw-SxBPD?q#4Ar85vP=WZ{mLiReq*(k* ts!*nVK-fzXmb&Yafp|OMh|OM&Pdwdl1{M8-2+@C-&2jr<94l(V{{a>Z(f$Ac literal 0 HcmV?d00001 diff --git a/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb17c7e8064d6156af449056c2cc5ea35d2f5d7 GIT binary patch literal 5069 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 KMNUMnLSTYNO)f$J literal 0 HcmV?d00001 diff --git a/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-20@2x.png b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a49e0b977ee213c53b705756e0d02fa488afbad2 GIT binary patch literal 1193 zcmV;a1XlZrP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1U^YbK~z{r&Dcq7 z8&w#XLIAeRf#EEC@c-+QYoWxG-B!x5_8VL#Lg&P71(L!5j5dx$F5?Domg4Cdr zxXyw}h=79H(24>FE=3%2KwMe@O}c$N9txU=1A3 z7y|$KbQmrk9)fMd!G_};ty-V~jsOP&@b|}e(8hMg!0q)k4CiPKDnJIDI)i_mxLw!j znJkR-3k|`^KszS`4RCnPA@Jr$n`zfS93rn*7l+`v2cqkaD+3vDctea1ig5Gz5be9U zemFVSML&Nro`!TXux>bqKU4|4H4bkCoWVbj4bm>m^}+Ps2rP}K=yz9+48V?iBkO{5 z>VdU!1UMkTABzLD^Q8<-?U6{Q3O%}GC-!&4MoCx`&e_(X0*!GpP=w!)=4j{MOvBXU z5^Z^=S9ko<5YShbU{bVE87X2K~z zKF@-~6#{|R-bvGz3tdonG+5Q?gGt>uwHF_ZGM!cxR|YcRaQVW!_}W4*ZFwRIg-3$A zz8s6|#$aC^NWn-}svGADM8JZ-S6OhlbZyOvaP{pT+L<>JP}m{TK7XlGcO0AC9Rsg= zz14~1^}yOV85o2s^WC&>4<=x8yFmKn`H1e=nTZtKGpw1lRp5AGqY5;};kt^zU*Ag6 zzIivpeN6Q!|*2grPM|HdOQa2JrRP-vq|##{A3ay zx+}u`5H`XQAo+iU0f&n|0U}1}`^h+5DkjML&t8Z^yc4gr^~3SPrV3yU9EPX(=b41A zi-!{M%ze0ou`ge&I9}8O4RE+4*_sW)Pt$SQ(#uiUk_j~o$BUf`kO8LxFBfB^{r5+} z+g{(oUoTDu^1eI^4)<~hJoQ>9+`SoRt?{@rkO7B9BoP9^`u1~c!STVU7FZj%n$6}~ zaqcqEoH%zVhCn|7nh{5VX2lVp{BOEBaqduD1)3A*>4?L>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D11m{HK~zXfz1K-h z6Hy$;@!klOGHs^?3bf3$)Gj~^HY~1i5>ToK&KjUZQPhLRL`_T@Js=@~hE;+@j8P0B zgb)uJPZ}b#f>Tl9H(uDGi6D6m2LS)EuRk z((*{AbOx42Z-hplD#fQEg)*cg#b9D_#td-AOsJ$Qj33CQWdCS6$>LJtY@8G^flR7Qym_8{OwRN_E*_s0vReD+R;IJO6zx9@%?r& z>*-|=dXHG;W;(s{9Ch_%KFp$JSx}c@jXrEf)aYr6{8igfIwz%c_aLoa?BB;-_5y}UZK-!0dez~!k zHQknr?nBvf_ks?2j?K4wQC?zO7Fl!Wuu5Bac)4$6c@p z!iu0iD+en2wO0aZp{t7l2l*#jcvt^ zzY@q>98l5gp%O^PTJ0_YlNTH)^9dUQE}{w`<#t$*nz{U0x*Cwrc81aDU@V9CYC(g9 sniv`{&>*-ZG@c+s>AyuhL4)ANUytLUO%(BtzyJUM07*qoM6N<$f^H|6I{*Lx literal 0 HcmV?d00001 diff --git a/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-29@2x.png b/iosApp/ARVIO/Assets.xcassets/AppIcon.appiconset/Icon-iPad-29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..cb3294652833e0e7ee8ab43a73496f68d323850e GIT binary patch literal 1592 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 Lc 0 { + ProgressView(value: item.progress) + .tint(ArvioTheme.gold) + .frame(width: 210) + } + } + .frame(width: 210, alignment: .leading) + } +} + +struct PrimaryButton: View { + let title: String + + var body: some View { + Text(title) + .font(.system(size: 15, weight: .bold)) + .foregroundStyle(Color.black) + .padding(.horizontal, 18) + .padding(.vertical, 13) + .background(RoundedRectangle(cornerRadius: 8).fill(ArvioTheme.gold)) + } +} + +struct SecondaryButton: View { + let title: String + + var body: some View { + Text(title) + .font(.system(size: 15, weight: .semibold)) + .foregroundStyle(ArvioTheme.textPrimary) + .padding(.horizontal, 18) + .padding(.vertical, 13) + .background(RoundedRectangle(cornerRadius: 8).fill(ArvioTheme.panel)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(ArvioTheme.border, lineWidth: 1)) + } +} diff --git a/iosApp/ARVIO/HomeView.swift b/iosApp/ARVIO/HomeView.swift new file mode 100644 index 000000000..c337b7f1a --- /dev/null +++ b/iosApp/ARVIO/HomeView.swift @@ -0,0 +1,101 @@ +import SwiftUI + +struct HomeView: View { + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 28) { + HeroSection(item: featuredItems[0]) + MediaRail(title: "Continue Watching", items: continueWatchingItems) + MediaRail(title: "Featured", items: featuredItems) + } + .padding(.horizontal, 28) + .padding(.bottom, 36) + } + } +} + +struct HeroSection: View { + let item: MediaItem + + var body: some View { + ZStack(alignment: .bottomLeading) { + PosterBackdrop(item: item) + .frame(height: 360) + .clipShape(RoundedRectangle(cornerRadius: 8)) + + LinearGradient(colors: [Color.black.opacity(0.0), Color.black.opacity(0.78)], startPoint: .center, endPoint: .bottom) + .clipShape(RoundedRectangle(cornerRadius: 8)) + + VStack(alignment: .leading, spacing: 12) { + Text(item.title) + .font(.system(size: 42, weight: .bold)) + .foregroundStyle(ArvioTheme.textPrimary) + + Text("\(item.subtitle) • \(item.year) • \(item.duration)") + .font(.system(size: 17, weight: .medium)) + .foregroundStyle(ArvioTheme.textSecondary) + + Text("A premium media hub experience for browsing, tracking and continuing your library across screens.") + .font(.system(size: 17)) + .foregroundStyle(ArvioTheme.textSecondary) + .lineLimit(2) + .frame(maxWidth: 580, alignment: .leading) + + HStack(spacing: 12) { + PrimaryButton(title: "Open Details") + SecondaryButton(title: "Add to Watchlist") + } + .padding(.top, 6) + } + .padding(28) + } + } +} + +struct MediaRail: View { + let title: String + let items: [MediaItem] + + var body: some View { + VStack(alignment: .leading, spacing: 14) { + Text(title) + .font(.system(size: 22, weight: .bold)) + .foregroundStyle(ArvioTheme.textPrimary) + + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 14) { + ForEach(items) { item in + MediaCard(item: item) + } + } + } + } + } +} + +struct CatalogView: View { + let title: String + let subtitle: String + let items: [MediaItem] + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 18) { + Text(title) + .font(.system(size: 38, weight: .bold)) + .foregroundStyle(ArvioTheme.textPrimary) + Text(subtitle) + .font(.system(size: 17)) + .foregroundStyle(ArvioTheme.textSecondary) + + LazyVGrid(columns: [GridItem(.adaptive(minimum: 210), spacing: 16)], spacing: 16) { + ForEach(items.isEmpty ? featuredItems : items) { item in + MediaCard(item: item) + } + } + .padding(.top, 8) + } + .padding(28) + } + } +} diff --git a/iosApp/ARVIO/Info.plist b/iosApp/ARVIO/Info.plist new file mode 100644 index 000000000..2a7b9ab8c --- /dev/null +++ b/iosApp/ARVIO/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDisplayName + ARVIO + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + LSRequiresIPhoneOS + + UILaunchScreen + + UIColorName + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/iosApp/ARVIO/Models.swift b/iosApp/ARVIO/Models.swift new file mode 100644 index 000000000..b7c3ebcb7 --- /dev/null +++ b/iosApp/ARVIO/Models.swift @@ -0,0 +1,31 @@ +import Foundation + +enum MediaKind: String { + case movie = "Movie" + case series = "TV Series" +} + +struct MediaItem: Identifiable, Hashable { + let id = UUID() + let title: String + let subtitle: String + let year: String + let duration: String + let rating: String + let kind: MediaKind + let progress: Double + let palette: [String] +} + +let featuredItems: [MediaItem] = [ + MediaItem(title: "Echoes of Dawn", subtitle: "S1 • E6 • New episode", year: "2026", duration: "45m", rating: "8.7", kind: .series, progress: 0.72, palette: ["#d99b4f", "#4b2b19"]), + MediaItem(title: "Neon Paradox", subtitle: "Cyber noir thriller", year: "2025", duration: "2h 10m", rating: "8.2", kind: .movie, progress: 0.0, palette: ["#2276ff", "#141b3c"]), + MediaItem(title: "Beyond the Wilds", subtitle: "S2 • E3", year: "2026", duration: "50m", rating: "8.0", kind: .series, progress: 0.28, palette: ["#9cbf6a", "#1d2d21"]), + MediaItem(title: "The Architect", subtitle: "Premium action cinema", year: "2025", duration: "1h 58m", rating: "7.9", kind: .movie, progress: 0.0, palette: ["#d64a36", "#241112"]) +] + +let continueWatchingItems: [MediaItem] = [ + MediaItem(title: "Night Watch", subtitle: "Resume episode", year: "2026", duration: "47m left", rating: "8.4", kind: .series, progress: 0.41, palette: ["#315f8d", "#081826"]), + MediaItem(title: "Deep Current", subtitle: "S1 • E4", year: "2026", duration: "19m left", rating: "8.1", kind: .series, progress: 0.64, palette: ["#1a9ec0", "#06242c"]), + MediaItem(title: "The Long Orbit", subtitle: "Continue movie", year: "2025", duration: "54m left", rating: "7.8", kind: .movie, progress: 0.52, palette: ["#7961c8", "#18152d"]) +] diff --git a/iosApp/ARVIO/RootView.swift b/iosApp/ARVIO/RootView.swift new file mode 100644 index 000000000..abed166b5 --- /dev/null +++ b/iosApp/ARVIO/RootView.swift @@ -0,0 +1,115 @@ +import SwiftUI + +enum ArvioTab: String, CaseIterable { + case home = "Home" + case movies = "Movies" + case series = "Series" + case watchlist = "Watchlist" + case search = "Search" + case settings = "Settings" +} + +struct RootView: View { + @State private var selectedTab: ArvioTab = .home + + var body: some View { + ZStack { + ArvioTheme.background.ignoresSafeArea() + + LinearGradient( + colors: [Color(hex: "#0b1b2a").opacity(0.65), Color.black.opacity(0.1), Color.black.opacity(0.72)], + startPoint: .topTrailing, + endPoint: .bottom + ) + .ignoresSafeArea() + + VStack(spacing: 0) { + TopNavigation(selectedTab: $selectedTab) + + Group { + switch selectedTab { + case .home: + HomeView() + case .movies: + CatalogView(title: "Movies", subtitle: "Curated cinema and recent releases.", items: featuredItems.filter { $0.kind == .movie }) + case .series: + CatalogView(title: "Series", subtitle: "Continue seasons and discover premium TV.", items: featuredItems.filter { $0.kind == .series }) + case .watchlist: + WatchlistView() + case .search: + SearchView() + case .settings: + SettingsView() + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + } + } +} + +struct TopNavigation: View { + @Binding var selectedTab: ArvioTab + + var body: some View { + HStack(spacing: 20) { + BrandMark() + + ForEach(ArvioTab.allCases, id: \.self) { tab in + Button { + selectedTab = tab + } label: { + Text(tab.rawValue) + .font(.system(size: 16, weight: selectedTab == tab ? .semibold : .medium)) + .foregroundStyle(selectedTab == tab ? ArvioTheme.textPrimary : ArvioTheme.textSecondary) + .padding(.horizontal, 16) + .padding(.vertical, 10) + .background( + RoundedRectangle(cornerRadius: 8) + .fill(selectedTab == tab ? ArvioTheme.gold.opacity(0.16) : Color.clear) + ) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(selectedTab == tab ? ArvioTheme.gold : Color.clear, lineWidth: 1) + ) + } + .buttonStyle(.plain) + } + + Spacer() + + Text("ARVIO") + .font(.system(size: 15, weight: .semibold)) + .foregroundStyle(ArvioTheme.textSecondary) + } + .padding(.horizontal, 28) + .padding(.top, 14) + .padding(.bottom, 10) + } +} + +struct BrandMark: View { + var body: some View { + ZStack { + Triangle() + .fill(LinearGradient(colors: [ArvioTheme.gold, Color(hex: "#f1c778")], startPoint: .top, endPoint: .bottom)) + .frame(width: 34, height: 42) + Triangle() + .fill(Color.black.opacity(0.26)) + .frame(width: 14, height: 28) + .offset(x: -1) + } + .frame(width: 52) + } +} + +struct Triangle: Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + path.move(to: CGPoint(x: rect.minX, y: rect.minY)) + path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY)) + path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY)) + path.closeSubpath() + return path + } +} diff --git a/iosApp/ARVIO/SearchView.swift b/iosApp/ARVIO/SearchView.swift new file mode 100644 index 000000000..87abb0912 --- /dev/null +++ b/iosApp/ARVIO/SearchView.swift @@ -0,0 +1,25 @@ +import SwiftUI + +struct SearchView: View { + @State private var query = "" + + var body: some View { + VStack(alignment: .leading, spacing: 22) { + Text("Search") + .font(.system(size: 38, weight: .bold)) + .foregroundStyle(ArvioTheme.textPrimary) + + TextField("Search movies, shows and episodes", text: $query) + .textInputAutocapitalization(.never) + .padding(16) + .background(RoundedRectangle(cornerRadius: 8).fill(ArvioTheme.panel)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(ArvioTheme.border, lineWidth: 1)) + .foregroundStyle(ArvioTheme.textPrimary) + + MediaRail(title: query.isEmpty ? "Suggested" : "Results", items: featuredItems) + + Spacer() + } + .padding(28) + } +} diff --git a/iosApp/ARVIO/SettingsView.swift b/iosApp/ARVIO/SettingsView.swift new file mode 100644 index 000000000..98b3fb92d --- /dev/null +++ b/iosApp/ARVIO/SettingsView.swift @@ -0,0 +1,39 @@ +import SwiftUI + +struct SettingsView: View { + var body: some View { + VStack(alignment: .leading, spacing: 18) { + Text("Settings") + .font(.system(size: 38, weight: .bold)) + .foregroundStyle(ArvioTheme.textPrimary) + + SettingsRow(title: "Profile", value: "Default") + SettingsRow(title: "Cloud sync", value: "Ready") + SettingsRow(title: "Trakt", value: "Connect later") + SettingsRow(title: "Playback", value: "Native iOS player") + + Spacer() + } + .padding(28) + } +} + +struct SettingsRow: View { + let title: String + let value: String + + var body: some View { + HStack { + Text(title) + .font(.system(size: 17, weight: .semibold)) + .foregroundStyle(ArvioTheme.textPrimary) + Spacer() + Text(value) + .font(.system(size: 15, weight: .medium)) + .foregroundStyle(ArvioTheme.textSecondary) + } + .padding(18) + .background(RoundedRectangle(cornerRadius: 8).fill(ArvioTheme.panel)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(ArvioTheme.border, lineWidth: 1)) + } +} diff --git a/iosApp/ARVIO/Theme.swift b/iosApp/ARVIO/Theme.swift new file mode 100644 index 000000000..35104daf2 --- /dev/null +++ b/iosApp/ARVIO/Theme.swift @@ -0,0 +1,23 @@ +import SwiftUI + +enum ArvioTheme { + static let background = Color(red: 0.031, green: 0.035, blue: 0.039) + static let panel = Color.white.opacity(0.075) + static let border = Color.white.opacity(0.12) + static let textPrimary = Color(red: 0.93, green: 0.93, blue: 0.93) + static let textSecondary = Color.white.opacity(0.68) + static let textTertiary = Color.white.opacity(0.44) + static let gold = Color(red: 1.0, green: 0.72, blue: 0.24) +} + +extension Color { + init(hex: String) { + let raw = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) + var value: UInt64 = 0 + Scanner(string: raw).scanHexInt64(&value) + let red = Double((value >> 16) & 0xff) / 255 + let green = Double((value >> 8) & 0xff) / 255 + let blue = Double(value & 0xff) / 255 + self.init(red: red, green: green, blue: blue) + } +} diff --git a/iosApp/ARVIO/WatchlistView.swift b/iosApp/ARVIO/WatchlistView.swift new file mode 100644 index 000000000..6a35535cf --- /dev/null +++ b/iosApp/ARVIO/WatchlistView.swift @@ -0,0 +1,11 @@ +import SwiftUI + +struct WatchlistView: View { + var body: some View { + CatalogView( + title: "Watchlist", + subtitle: "Movies and shows saved for later.", + items: featuredItems + continueWatchingItems + ) + } +} diff --git a/iosApp/project.yml b/iosApp/project.yml new file mode 100644 index 000000000..d889e0825 --- /dev/null +++ b/iosApp/project.yml @@ -0,0 +1,28 @@ +name: ARVIO +options: + minimumXcodeGenVersion: 2.40.0 + deploymentTarget: + iOS: "17.0" +settings: + base: + SWIFT_VERSION: 5.10 + IPHONEOS_DEPLOYMENT_TARGET: "17.0" + DEVELOPMENT_TEAM: YSKCRJKAF3 + CODE_SIGN_STYLE: Automatic + TARGETED_DEVICE_FAMILY: "1,2" +targets: + ARVIO: + type: application + platform: iOS + sources: + - path: ARVIO + settings: + base: + PRODUCT_BUNDLE_IDENTIFIER: com.arvio.ios + PRODUCT_NAME: ARVIO + INFOPLIST_FILE: ARVIO/Info.plist + ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon + MARKETING_VERSION: 0.1.0 + CURRENT_PROJECT_VERSION: 1 + GENERATE_INFOPLIST_FILE: NO + ENABLE_USER_SCRIPT_SANDBOXING: NO