diff --git a/.github/workflows/pull_request_test.yml b/.github/workflows/pull_request_test.yml index 596769ec..67a7f93b 100644 --- a/.github/workflows/pull_request_test.yml +++ b/.github/workflows/pull_request_test.yml @@ -7,7 +7,7 @@ on: jobs: build_test: - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v2 @@ -21,11 +21,12 @@ jobs: - name: Setup Xcode version uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: "14.3" + xcode-version: "15.3" - - uses: swift-actions/setup-swift@65540b95f51493d65f5e59e97dcef9629ddf11bf + - name: Setup Swift Version + uses: swift-actions/setup-swift@v2 with: - swift-version: "5.8.0" + swift-version: "5.10" - name: Get swift version run: swift --version @@ -43,4 +44,4 @@ jobs: run: tuist fetch - name: Tuist Build Test - run: tuist build + run: tuist build App diff --git a/.github/workflows/upload_testflight.yml b/.github/workflows/upload_testflight.yml index 2a6bcd03..6427ea9a 100644 --- a/.github/workflows/upload_testflight.yml +++ b/.github/workflows/upload_testflight.yml @@ -7,7 +7,7 @@ on: jobs: upload_testflight: - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v2 @@ -30,11 +30,12 @@ jobs: - name: Setup Xcode version uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: "14.3" + xcode-version: "15.3" - - uses: swift-actions/setup-swift@65540b95f51493d65f5e59e97dcef9629ddf11bf + - name: Setup Swift Version + uses: swift-actions/setup-swift@v2 with: - swift-version: "5.8.0" + swift-version: "5.10" - name: Install Tuist run: curl -Ls https://install.tuist.io|bash diff --git a/Plugins/EnvironmentPlugin/ProjectDescriptionHelpers/Environment.swift b/Plugins/EnvironmentPlugin/ProjectDescriptionHelpers/Environment.swift index 334bbbb2..4b3d4818 100644 --- a/Plugins/EnvironmentPlugin/ProjectDescriptionHelpers/Environment.swift +++ b/Plugins/EnvironmentPlugin/ProjectDescriptionHelpers/Environment.swift @@ -20,6 +20,7 @@ public extension String { let date = Date() let formatter = DateFormatter() formatter.dateFormat = "yyyy.MM.dd.HH.mm" + formatter.locale = Locale(identifier: "ko_KR") return formatter.string(from: date) } } diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index 6c5680b8..696a5eb4 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -8,26 +8,26 @@ let project = Project.makeProject( entitlementsPath: .relativeToManifest("App.entitlements"), hasResource: true, appExtensionTarget: [ -// Project.appExtensionTarget( -// name: "Widget", -// plist: .extendingDefault( -// with: .widgetInfoPlist -// ), -// resources: [ -// "Resources/Model.xcdatamodeld", -// "Resources/total_stationList.json", -// "Widget/Resources/**", -// ], -// entitlements: .file( -// path: .relativeToRoot( -// "Projects/App/Widget.entitlements" -// ) -// ), -// dependencies: [ -// .mainFeature, -// .data, -// ] -// ) + Project.appExtensionTarget( + name: "Widget", + plist: .extendingDefault( + with: .widgetInfoPlist + ), + resources: [ + "Resources/Model.xcdatamodeld", + "Resources/total_stationList.json", + "Widget/Resources/**", + ], + entitlements: .file( + path: .relativeToRoot( + "Projects/App/Widget.entitlements" + ) + ), + dependencies: [ + .mainFeature, + .data, + ] + ) ], packages: [ .remote( diff --git a/Projects/App/Widget/ArrivalInfo/ArrivalInfoProvider.swift b/Projects/App/Widget/ArrivalInfo/ArrivalInfoProvider.swift index 3d99281f..917d1935 100644 --- a/Projects/App/Widget/ArrivalInfo/ArrivalInfoProvider.swift +++ b/Projects/App/Widget/ArrivalInfo/ArrivalInfoProvider.swift @@ -23,6 +23,7 @@ struct ArrivalInfoProvider: AppIntentTimelineProvider { responses: useCase.responses ) } + func snapshot( for configuration: ArrivalInfoIntent, in context: Context @@ -33,6 +34,7 @@ struct ArrivalInfoProvider: AppIntentTimelineProvider { responses: useCase.responses ) } + func timeline( for configuration: ArrivalInfoIntent, in context: Context diff --git a/Projects/App/Widget/ArrivalInfo/Medium/ArrivalInfoMediumWidget.swift b/Projects/App/Widget/ArrivalInfo/ArrivalInfoWidget.swift similarity index 51% rename from Projects/App/Widget/ArrivalInfo/Medium/ArrivalInfoMediumWidget.swift rename to Projects/App/Widget/ArrivalInfo/ArrivalInfoWidget.swift index c9cc41a2..9f363c74 100644 --- a/Projects/App/Widget/ArrivalInfo/Medium/ArrivalInfoMediumWidget.swift +++ b/Projects/App/Widget/ArrivalInfo/ArrivalInfoWidget.swift @@ -1,8 +1,8 @@ // -// ArrivalInfoMediumWidget.swift +// ArrivalInfoWidget.swift // Widget // -// Created by gnksbm on 4/12/24. +// Created by gnksbm on 4/13/24. // Copyright © 2024 Pepsi-Club. All rights reserved. // @@ -10,8 +10,8 @@ import WidgetKit import SwiftUI @available(iOS 17.0, *) -struct ArrivalInfoMediumWidget: Widget { - let kind: String = "ArrivalInfoMedium" +struct ArrivalInfoWidget: Widget { + let kind: String = "ArrivalInfo" var body: some WidgetConfiguration { AppIntentConfiguration( @@ -19,10 +19,15 @@ struct ArrivalInfoMediumWidget: Widget { intent: ArrivalInfoIntent.self, provider: ArrivalInfoProvider() ) { entry in - ArrivalInfoMediumView( + ArrivalInfoView( entry: entry ) } - .supportedFamilies([.systemMedium]) + .supportedFamilies([ + .systemSmall, + .systemMedium + ]) + .configurationDisplayName("즐겨찾기") + .description("실시간 도착정보를 확인할 수 있어요") } } diff --git a/Projects/App/Widget/ArrivalInfo/ArrivalInfoIntent.swift b/Projects/App/Widget/ArrivalInfo/Intent/ArrivalInfoIntent.swift similarity index 60% rename from Projects/App/Widget/ArrivalInfo/ArrivalInfoIntent.swift rename to Projects/App/Widget/ArrivalInfo/Intent/ArrivalInfoIntent.swift index 9c75e78b..50bd9e0b 100644 --- a/Projects/App/Widget/ArrivalInfo/ArrivalInfoIntent.swift +++ b/Projects/App/Widget/ArrivalInfo/Intent/ArrivalInfoIntent.swift @@ -12,9 +12,9 @@ import AppIntents @available(iOS 17.0, *) struct ArrivalInfoIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource = "Configuration" - static var description = IntentDescription("This is an example widget.") - // An example configurable parameter. - @Parameter(title: "Favorite Emoji", default: "😃") - var favoriteEmoji: String + @Parameter(title: "정류장", optionsProvider: BusStopOptionProvider()) + var busStop: String + @Parameter(title: "버스", optionsProvider: BusOptionProvider()) + var bus: String } diff --git a/Projects/App/Widget/ArrivalInfo/Intent/Parameter/BusOptionProvider.swift b/Projects/App/Widget/ArrivalInfo/Intent/Parameter/BusOptionProvider.swift new file mode 100644 index 00000000..bc6ce342 --- /dev/null +++ b/Projects/App/Widget/ArrivalInfo/Intent/Parameter/BusOptionProvider.swift @@ -0,0 +1,27 @@ +// +// BusOptionProvider.swift +// AppUITests +// +// Created by gnksbm on 4/13/24. +// Copyright © 2024 Pepsi-Club. All rights reserved. +// + +import AppIntents + +import CoreDataService +import Domain + +struct BusOptionProvider: DynamicOptionsProvider { +// let coreDataService = DefaultCoreDataService() + func defaultResult() async -> String? { + "" + } + + func results() async throws -> [String] { +// let responses = try coreDataService.fetch( +// type: FavoritesBusStopResponse.self +// ) +// return responses.flatMap { $0.busIds } + [] + } +} diff --git a/Projects/App/Widget/ArrivalInfo/Intent/Parameter/BusStopOptionProvider.swift b/Projects/App/Widget/ArrivalInfo/Intent/Parameter/BusStopOptionProvider.swift new file mode 100644 index 00000000..bbf3a7f7 --- /dev/null +++ b/Projects/App/Widget/ArrivalInfo/Intent/Parameter/BusStopOptionProvider.swift @@ -0,0 +1,27 @@ +// +// BusStopOptionProvider.swift +// AppUITests +// +// Created by gnksbm on 4/13/24. +// Copyright © 2024 Pepsi-Club. All rights reserved. +// + +import AppIntents + +import CoreDataService +import Domain + +struct BusStopOptionProvider: DynamicOptionsProvider { +// let coreDataService = DefaultCoreDataService() + func defaultResult() async -> String? { + "" + } + + func results() async throws -> [String] { +// let responses = try coreDataService.fetch( +// type: FavoritesBusStopResponse.self +// ) +// return responses.map { $0.busStopId } + [] + } +} diff --git a/Projects/App/Widget/ArrivalInfo/Small/ArrivalInfoSmallWidget.swift b/Projects/App/Widget/ArrivalInfo/Small/ArrivalInfoSmallWidget.swift deleted file mode 100644 index f3e036a2..00000000 --- a/Projects/App/Widget/ArrivalInfo/Small/ArrivalInfoSmallWidget.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// ArrivalInfoSmallWidget.swift -// WidgetExtension -// -// Created by gnksbm on 4/4/24. -// Copyright © 2024 Pepsi-Club. All rights reserved. -// - -import WidgetKit -import SwiftUI - -@available(iOS 17.0, *) -struct ArrivalInfoSmallWidget: Widget { - let kind: String = "ArrivalInfoSmall" - - var body: some WidgetConfiguration { - AppIntentConfiguration( - kind: kind, - intent: ArrivalInfoIntent.self, - provider: ArrivalInfoProvider() - ) { entry in - ArrivalInfoSmallView( - entry: entry - ) - } - .supportedFamilies([.systemMedium]) - } -} diff --git a/Projects/App/Widget/ArrivalInfo/Medium/ArrivalInfoMediumView.swift b/Projects/App/Widget/ArrivalInfo/View/ArrivalInfoMediumView.swift similarity index 89% rename from Projects/App/Widget/ArrivalInfo/Medium/ArrivalInfoMediumView.swift rename to Projects/App/Widget/ArrivalInfo/View/ArrivalInfoMediumView.swift index 65fb6b6a..1f42a4de 100644 --- a/Projects/App/Widget/ArrivalInfo/Medium/ArrivalInfoMediumView.swift +++ b/Projects/App/Widget/ArrivalInfo/View/ArrivalInfoMediumView.swift @@ -32,7 +32,6 @@ struct ArrivalInfoMediumView: View { arrivalInfoView } } - .widgetBackground(Color.white) .widgetURL(url) } @@ -83,6 +82,16 @@ struct ArrivalInfoMediumView: View { @available(iOS 17.0, *) struct ArrivalInfoMediumView_Preview: PreviewProvider { static var previews: some View { + ArrivalInfoMediumView( + entry: ArrivalInfoEntry( + date: .now, + configuration: .init() + ) + ) + .widgetBackground() + .previewContext( + WidgetPreviewContext(family: .systemMedium) + ) ArrivalInfoMediumView( entry: ArrivalInfoEntry( date: .now, @@ -90,6 +99,7 @@ struct ArrivalInfoMediumView_Preview: PreviewProvider { responses: .mock ) ) + .widgetBackground() .previewContext( WidgetPreviewContext(family: .systemMedium) ) diff --git a/Projects/App/Widget/ArrivalInfo/Small/ArrivalInfoSmallView.swift b/Projects/App/Widget/ArrivalInfo/View/ArrivalInfoSmallView.swift similarity index 89% rename from Projects/App/Widget/ArrivalInfo/Small/ArrivalInfoSmallView.swift rename to Projects/App/Widget/ArrivalInfo/View/ArrivalInfoSmallView.swift index 72e23ac7..c962db85 100644 --- a/Projects/App/Widget/ArrivalInfo/Small/ArrivalInfoSmallView.swift +++ b/Projects/App/Widget/ArrivalInfo/View/ArrivalInfoSmallView.swift @@ -33,7 +33,6 @@ struct ArrivalInfoSmallView: View { arrivalInfoView } } - .widgetBackground(Color.white) .widgetURL(url) } @@ -84,6 +83,16 @@ struct ArrivalInfoSmallView: View { @available(iOS 17.0, *) struct ArrivalInfoSmallView_Preview: PreviewProvider { static var previews: some View { + ArrivalInfoSmallView( + entry: ArrivalInfoEntry( + date: .now, + configuration: .init() + ) + ) + .widgetBackground() + .previewContext( + WidgetPreviewContext(family: .systemSmall) + ) ArrivalInfoSmallView( entry: ArrivalInfoEntry( date: .now, @@ -91,6 +100,7 @@ struct ArrivalInfoSmallView_Preview: PreviewProvider { responses: .mock ) ) + .widgetBackground() .previewContext( WidgetPreviewContext(family: .systemSmall) ) diff --git a/Projects/App/Widget/ArrivalInfo/View/ArrivalInfoView.swift b/Projects/App/Widget/ArrivalInfo/View/ArrivalInfoView.swift new file mode 100644 index 00000000..a95a3b63 --- /dev/null +++ b/Projects/App/Widget/ArrivalInfo/View/ArrivalInfoView.swift @@ -0,0 +1,60 @@ +// +// ArrivalInfoView.swift +// Widget +// +// Created by gnksbm on 4/13/24. +// Copyright © 2024 Pepsi-Club. All rights reserved. +// + +import SwiftUI +import WidgetKit + +@available (iOS 17.0, *) +struct ArrivalInfoView: View { + var entry: ArrivalInfoProvider.Entry + @Environment(\.widgetFamily) var widgetFamily + + var body: some View { + view.widgetBackground(Color.white) + } + + @ViewBuilder + var view: some View { + switch widgetFamily { + case .systemSmall: + ArrivalInfoSmallView(entry: entry) + case .systemMedium: + ArrivalInfoMediumView(entry: entry) + default: + EmptyView() + } + } +} + +#if DEBUG +@available(iOS 17.0, *) +struct ArrivalInfoView_Preview: PreviewProvider { + static var previews: some View { + ArrivalInfoView( + entry: ArrivalInfoEntry( + date: .now, + configuration: .init(), + responses: .mock + ) + ) + .previewContext( + WidgetPreviewContext(family: .systemSmall) + ) + ArrivalInfoView( + entry: ArrivalInfoEntry( + date: .now, + configuration: .init(), + responses: .mock + ) + ) + .previewContext( + WidgetPreviewContext(family: .systemMedium) + ) + } +} +#endif diff --git a/Projects/App/Widget/ArrivalInfo/View/RefreshView.swift b/Projects/App/Widget/ArrivalInfo/View/RefreshView.swift index e0136ce5..56a3153d 100644 --- a/Projects/App/Widget/ArrivalInfo/View/RefreshView.swift +++ b/Projects/App/Widget/ArrivalInfo/View/RefreshView.swift @@ -9,6 +9,7 @@ import SwiftUI import Core +import WidgetKit @available(iOS 17.0, *) struct RefreshView: View { @@ -16,9 +17,12 @@ struct RefreshView: View { var body: some View { HStack { - Spacer() - Text(entry.date.toString(dateFormat: "HH:mm 업데이트")) - .font(.caption) + Text( + entry.date.toString( + dateFormat: "HH:mm 업데이트" + ) + ) + .font(.caption) Button(intent: entry.configuration) { Image(systemName: "arrow.clockwise") } @@ -26,3 +30,29 @@ struct RefreshView: View { } } } + +#if DEBUG +@available(iOS 17.0, *) +struct RefreshView_Preview: PreviewProvider { + static var previews: some View { + RefreshView( + entry: .init( + date: .now, + configuration: .init(), + responses: .mock + ) + ) + .widgetBackground() + .previewContext(WidgetPreviewContext(family: .systemSmall)) + RefreshView( + entry: .init( + date: .now, + configuration: .init(), + responses: .mock + ) + ) + .widgetBackground() + .previewContext(WidgetPreviewContext(family: .systemMedium)) + } +} +#endif diff --git a/Projects/App/Widget/Extension/View+.swift b/Projects/App/Widget/Extension/View+.swift index 6b0e4f14..62b55452 100644 --- a/Projects/App/Widget/Extension/View+.swift +++ b/Projects/App/Widget/Extension/View+.swift @@ -9,7 +9,9 @@ import SwiftUI extension View { - func widgetBackground(_ backgroundView: some View) -> some View { + func widgetBackground( + _ backgroundView: some View = Color.white + ) -> some View { if #available(iOSApplicationExtension 17.0, *) { return containerBackground(for: .widget) { backgroundView diff --git a/Projects/App/Widget/NearByStop/NearByStopWidget.swift b/Projects/App/Widget/NearByStop/NearByStopWidget.swift index 1be09caa..f24c9ee8 100644 --- a/Projects/App/Widget/NearByStop/NearByStopWidget.swift +++ b/Projects/App/Widget/NearByStop/NearByStopWidget.swift @@ -19,5 +19,7 @@ struct NearByStopWidget: Widget { NearByStopView(entry: entry) } .supportedFamilies([.systemSmall]) + .configurationDisplayName("주변정류장") + .description("근처에 있는 정류장을 빠르게 확인하세요") } } diff --git a/Projects/App/Widget/NearByStop/NearByStopView.swift b/Projects/App/Widget/NearByStop/View/NearByStopView.swift similarity index 100% rename from Projects/App/Widget/NearByStop/NearByStopView.swift rename to Projects/App/Widget/NearByStop/View/NearByStopView.swift diff --git a/Projects/App/Widget/WMBWidgetBundle.swift b/Projects/App/Widget/WMBWidgetBundle.swift index 45f65b62..05bed074 100644 --- a/Projects/App/Widget/WMBWidgetBundle.swift +++ b/Projects/App/Widget/WMBWidgetBundle.swift @@ -14,8 +14,7 @@ struct WMBWidgetBundle: WidgetBundle { var body: some Widget { NearByStopWidget() if #available(iOS 17, *) { - ArrivalInfoSmallWidget() - ArrivalInfoMediumWidget() + ArrivalInfoWidget() } } } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 1d96b6d8..417ab449 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -102,7 +102,7 @@ platform :ios do keychain_password: ENV["KEYCHAIN_PASSWORD"], app_identifier: [ "com.Pepsi-Club.WhereMyBus", - # "com.Pepsi-Club.WhereMyBus.Widget" + "com.Pepsi-Club.WhereMyBus.Widget" ], readonly: true ) @@ -113,7 +113,7 @@ platform :ios do keychain_password: ENV["KEYCHAIN_PASSWORD"], app_identifier: [ "com.Pepsi-Club.WhereMyBus", - # "com.Pepsi-Club.WhereMyBus.Widget" + "com.Pepsi-Club.WhereMyBus.Widget" ], readonly: true )