diff --git a/.github/workflows/ios_emerge_upload_adhoc.yml b/.github/workflows/ios_emerge_upload_adhoc.yml index 65c07c5d..5cdce776 100644 --- a/.github/workflows/ios_emerge_upload_adhoc.yml +++ b/.github/workflows/ios_emerge_upload_adhoc.yml @@ -36,6 +36,11 @@ jobs: CERTIFICATE_BASE64: ${{ secrets.IOS_DIST_SIGNING_KEY_BASE64 }} run: | echo $CERTIFICATE_BASE64 | base64 --decode > signing-cert.p12 + - name: Replace API key in Constants file + run: | + sed -i '' "s/API_KEY/$ETDISTRIBUTION_API_KEY/g" HackerNews/Utils/Constants.swift + env: + ETDISTRIBUTION_API_KEY: ${{ secrets.ETDISTRIBUTION_API_KEY_IOS }} - name: Build & upload iOS AdHoc binary to Emerge Tools run: bundle exec fastlane ios build_upload_emerge env: diff --git a/ios/HackerNews.xcodeproj/project.pbxproj b/ios/HackerNews.xcodeproj/project.pbxproj index b0243131..b0f604f6 100644 --- a/ios/HackerNews.xcodeproj/project.pbxproj +++ b/ios/HackerNews.xcodeproj/project.pbxproj @@ -28,6 +28,8 @@ F48E9DA42D4D2A3500FD8B30 /* Common in Embed Frameworks */ = {isa = PBXBuildFile; productRef = F48E9DA22D4D2A3500FD8B30 /* Common */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; F48E9DA72D4D2A3C00FD8B30 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = F48E9DA62D4D2A3C00FD8B30 /* Common */; }; F48E9DA82D4D2A3C00FD8B30 /* Common in Embed Frameworks */ = {isa = PBXBuildFile; productRef = F48E9DA62D4D2A3C00FD8B30 /* Common */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + F48E9ECB2D4D691600FD8B30 /* ETDistribution in Frameworks */ = {isa = PBXBuildFile; productRef = F48E9ECA2D4D691600FD8B30 /* ETDistribution */; }; + F48E9FDB2D51690400FD8B30 /* ETDistribution in Embed Frameworks */ = {isa = PBXBuildFile; productRef = F48E9ECA2D4D691600FD8B30 /* ETDistribution */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -73,6 +75,7 @@ dstSubfolderSpec = 10; files = ( F45F6F4A2D4D2185003FA9A3 /* Common in Embed Frameworks */, + F48E9FDB2D51690400FD8B30 /* ETDistribution in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -182,6 +185,7 @@ files = ( F45F6EA52D4D1E50003FA9A3 /* Common in Frameworks */, A47309B42AA29D9600201376 /* SwiftSoup in Frameworks */, + F48E9ECB2D4D691600FD8B30 /* ETDistribution in Frameworks */, A4D28AEE2C237E2A007F20D0 /* SnapshotPreferences in Frameworks */, F45F703E2D4D2695003FA9A3 /* Fonts in Frameworks */, A495B2952BFEA11B00A8A8A9 /* Reaper in Frameworks */, @@ -358,6 +362,7 @@ A4D28AED2C237E2A007F20D0 /* SnapshotPreferences */, F45F6EA42D4D1E50003FA9A3 /* Common */, F45F703D2D4D2695003FA9A3 /* Fonts */, + F48E9ECA2D4D691600FD8B30 /* ETDistribution */, ); productName = HackerNews; productReference = A42705792A4293B10057E439 /* HackerNews.app */; @@ -479,6 +484,7 @@ A495A6642CED57BB009A2A6B /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */, F45F6E532D4D1D3E003FA9A3 /* XCLocalSwiftPackageReference "Packages/Common" */, F45F6F4C2D4D2554003FA9A3 /* XCLocalSwiftPackageReference "Packages/Fonts" */, + F48E9EC92D4D691600FD8B30 /* XCRemoteSwiftPackageReference "ETDistribution" */, ); productRefGroup = A427057A2A4293B10057E439 /* Products */; projectDirPath = ""; @@ -745,6 +751,7 @@ "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; + EXCLUDED_SOURCE_FILE_NAMES = "ETDistribution*"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "HackerNews/Hacker-News-Info.plist"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.news"; @@ -787,6 +794,7 @@ "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; + EXCLUDED_SOURCE_FILE_NAMES = "ETDistribution*"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "HackerNews/Hacker-News-Info.plist"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.news"; @@ -1229,6 +1237,14 @@ kind = branch; }; }; + F48E9EC92D4D691600FD8B30 /* XCRemoteSwiftPackageReference "ETDistribution" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/EmergeTools/ETDistribution.git"; + requirement = { + kind = upToNextMinorVersion; + minimumVersion = 0.2.1; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -1297,6 +1313,11 @@ package = F45F6E532D4D1D3E003FA9A3 /* XCLocalSwiftPackageReference "Packages/Common" */; productName = Common; }; + F48E9ECA2D4D691600FD8B30 /* ETDistribution */ = { + isa = XCSwiftPackageProductDependency; + package = F48E9EC92D4D691600FD8B30 /* XCRemoteSwiftPackageReference "ETDistribution" */; + productName = ETDistribution; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = A42705712A4293B10057E439 /* Project object */; diff --git a/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1379f320..47eeebdb 100644 --- a/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -10,6 +10,15 @@ "version" : "1.0.2" } }, + { + "identity" : "etdistribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/EmergeTools/ETDistribution.git", + "state" : { + "revision" : "6643aa6332ab3ebc629a3c4fefcfcf2bfe35c672", + "version" : "0.2.1" + } + }, { "identity" : "flyingfox", "kind" : "remoteSourceControl", diff --git a/ios/HackerNews/HNApp.swift b/ios/HackerNews/HNApp.swift index c7407387..c6577b11 100644 --- a/ios/HackerNews/HNApp.swift +++ b/ios/HackerNews/HNApp.swift @@ -74,6 +74,11 @@ struct Hacker_NewsApp: App { .onOpenURL { url in handleDeepLink(url) } +#if ADHOC + .onAppear() { + AutoUpdateManager.checkForUpdates() + } +#endif } } diff --git a/ios/HackerNews/Settings/SettingsScreen.swift b/ios/HackerNews/Settings/SettingsScreen.swift index dd409f9d..f1085214 100644 --- a/ios/HackerNews/Settings/SettingsScreen.swift +++ b/ios/HackerNews/Settings/SettingsScreen.swift @@ -65,6 +65,26 @@ struct SettingsScreen: View { url: URL(string: "https://www.twitter.com/heyrikin")!) } ) + +#if ADHOC + SettingsRow( + text: "Check for Updates", + leadingIcon: { + Image(systemName: "icloud.and.arrow.down") + .font(.system(size: 12)) + .foregroundStyle(.blue) + }, + trailingIcon: { + Image(systemName: "arrow.up.right") + .font(.system(size: 12)) + .foregroundStyle(.onBackground) + + }, + action: { + AutoUpdateManager.checkForUpdates() + } + ) +#endif SettingsRow( text: "Send Feedback", diff --git a/ios/HackerNews/Updates/AutoUpdateManager.swift b/ios/HackerNews/Updates/AutoUpdateManager.swift new file mode 100644 index 00000000..93c2056a --- /dev/null +++ b/ios/HackerNews/Updates/AutoUpdateManager.swift @@ -0,0 +1,38 @@ +// +// AutoUpdatemanager.swift +// HackerNews +// +// Created by Itay Brenner on 31/1/25. +// + +#if ADHOC +import UIKit +import Foundation +import ETDistribution + +struct AutoUpdateManager { + @MainActor static func checkForUpdates() { + let params = CheckForUpdateParams(apiKey: Constants.Distribution.apiKey) + ETDistribution.shared.checkForUpdate(params: params) { result in + switch result { + case .success(let releaseInfo): + if let releaseInfo { + print("Update found: \(releaseInfo)") + guard let url = ETDistribution.shared.buildUrlForInstall(releaseInfo.downloadUrl) else { + return + } + DispatchQueue.main.async { + UIApplication.shared.open(url) { _ in + exit(0) + } + } + } else { + print("Already up to date") + } + case .failure(let error): + print("Error checking for update: \(error)") + } + } + } +} +#endif diff --git a/ios/HackerNews/Utils/Constants.swift b/ios/HackerNews/Utils/Constants.swift new file mode 100644 index 00000000..499273d1 --- /dev/null +++ b/ios/HackerNews/Utils/Constants.swift @@ -0,0 +1,14 @@ +// +// Constants.swift +// HackerNews +// +// Created by Itay Brenner on 31/1/25. +// + +import Foundation + +enum Constants { + enum Distribution { + static let apiKey = "API_KEY" + } +}