diff --git a/iOS-NOTTODO/Settings.bundle/Root.plist b/iOS-NOTTODO/Settings.bundle/Root.plist index 102380b9..71527a74 100644 --- a/iOS-NOTTODO/Settings.bundle/Root.plist +++ b/iOS-NOTTODO/Settings.bundle/Root.plist @@ -2,6 +2,8 @@ + ApplicationGroupContainerIdentifier + group.nottodo.iOS-NOTTODO StringsTable Root PreferenceSpecifiers diff --git a/iOS-NOTTODO/Widget-NOTTODO/AppIntent.swift b/iOS-NOTTODO/Widget-NOTTODO/AppIntent.swift new file mode 100644 index 00000000..f7be937d --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/AppIntent.swift @@ -0,0 +1,34 @@ +// +// AppIntent.swift +// Widget-NOTTODO +// +// Created by 강윤서 on 4/14/24. +// + +import WidgetKit +import AppIntents + +struct ConfigurationAppIntent: WidgetConfigurationIntent { + static var title: LocalizedStringResource = "Configuration" +} + +struct ToggleButtonIntent: AppIntent { + static var title: LocalizedStringResource = .init(stringLiteral: "Mission's State") + + @Parameter(title: "Mission ID") + var id: Int + + @Parameter(title: "Mission status") + var status: String + + init() { } + init(id: Int, status: String) { + self.id = id + self.status = status == CompletionStatus.UNCHECKED.rawValue ? CompletionStatus.CHECKED.rawValue : CompletionStatus.UNCHECKED.rawValue + } + + func perform() async throws -> some IntentResult { + _ = try await WidgetService.shared.updateMission(id: id, status: status) + return .result() + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Global/Extensions/Formatter.swift b/iOS-NOTTODO/Widget-NOTTODO/Global/Extensions/Formatter.swift new file mode 100644 index 00000000..2ba9253b --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Global/Extensions/Formatter.swift @@ -0,0 +1,18 @@ +// +// Formatter.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 5/12/24. +// + +import Foundation + +struct Formatter { + static func dateFormatterString(format: String?, date: Date) -> String { + let formatter = Foundation.DateFormatter() + formatter.dateFormat = format ?? "yyyy-MM-dd" + formatter.locale = Locale(identifier: "ko_KR") + let convertStr = formatter.string(from: date) + return convertStr + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Network/Base/NetworkError.swift b/iOS-NOTTODO/Widget-NOTTODO/Network/Base/NetworkError.swift new file mode 100644 index 00000000..3a051add --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Network/Base/NetworkError.swift @@ -0,0 +1,17 @@ +// +// NetworkError.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 5/11/24. +// + +import Foundation + +enum NetworkError: Error { + case invalidResponse + case networkError + case dataParsingError + case invalidRequestParameters + case encodingFailed + case internalError(message: String) +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Network/DataModel/QuoteResponseDTO.swift b/iOS-NOTTODO/Widget-NOTTODO/Network/DataModel/QuoteResponseDTO.swift new file mode 100644 index 00000000..f2b0b99b --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Network/DataModel/QuoteResponseDTO.swift @@ -0,0 +1,14 @@ +// +// QuoteResponseDTO.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 5/10/24. +// + +import Foundation + +struct QuoteResponseDTO: Codable { + let id: Int + let description: String + let author: String +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Network/Service/WidgetService.swift b/iOS-NOTTODO/Widget-NOTTODO/Network/Service/WidgetService.swift new file mode 100644 index 00000000..4cff900e --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Network/Service/WidgetService.swift @@ -0,0 +1,205 @@ +// +// WidgetService.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 5/10/24. +// + +import Foundation +import SwiftUI + +typealias QuoteData = GeneralResponse +typealias DailyMissionData = GeneralArrayResponse +typealias UpdateMissionStatus = GeneralResponse + +struct WidgetService { + @AppStorage(DefaultKeys.accessToken, store: UserDefaults.shared) var accessToken: String = "" + + static let shared = WidgetService() + private init() {} + + let session = URLSession(configuration: URLSessionConfiguration.default, delegate: URLSessionLoggingDelegate(), delegateQueue: nil) + + func fetchWiseSaying() async throws -> QuoteResponseDTO { + do { + return try await getWiseSaying( + from: generateURL(constant: URLConstant.quote)) + } catch { + switch error { + case NetworkError.networkError: + print("네트워크 에러가 발생") + case NetworkError.invalidResponse: + print("유효하지 않은 응답") + case NetworkError.dataParsingError: + print("데이터 파싱 실패") + default: + print("알 수 없는 에러 발생") + } + throw error + } + } + + func fetchDailyMissoin(date: String) async throws -> [DailyMissionResponseDTO] { + do { + return try await getDailyMission( + from: generateURL(constant: URLConstant.recommend + URLConstant.dailyMission, parameter: date)) + } catch { + switch error { + case NetworkError.networkError: + print("네트워크 에러가 발생") + case NetworkError.invalidResponse: + print("유효하지 않은 응답") + case NetworkError.dataParsingError: + print("데이터 파싱 실패") + default: + print("알 수 없는 에러 발생") + } + throw error + } + } + + func updateMission(id: Int, status: String) async throws { + do { + try await patchUpdateMission( + from: generateURL(constant: URLConstant.recommend, parameter: "\(id)" + "/check"), + id: id, + requestData: status) + + let dailyMission = try await fetchDailyMissoin(date: Formatter.dateFormatterString(format: nil, date: Date())) + UserDefaults.shared?.setSharedCustomArray(dailyMission, forKey: "dailyMission") + } catch { + switch error { + case NetworkError.networkError: + print("네트워크 에러가 발생") + case NetworkError.invalidResponse: + print("유효하지 않은 응답") + case NetworkError.dataParsingError: + print("데이터 파싱 실패") + case NetworkError.encodingFailed: + print("데이터 인코딩 실패") + case NetworkError.invalidRequestParameters: + print("유효하지 않은 파라미터") + default: + print("알 수 없는 에러 발생") + } + throw error + } + } + + private func getWiseSaying(from url: URL) async throws -> QuoteResponseDTO { + let (data, response) = try await session.data(from: url) + + guard let httpResponse = response as? HTTPURLResponse else { + throw NetworkError.networkError + } + + guard (200..<300).contains(httpResponse.statusCode) else { + throw NetworkError.invalidResponse + } + + do { + let result = try JSONDecoder().decode(QuoteData.self, from: data) + guard let responseData = result.data else { + throw NetworkError.dataParsingError + } + return responseData + } catch { + throw NetworkError.dataParsingError + } + } + + private func getDailyMission(from url: URL) async throws -> [DailyMissionResponseDTO] { + var request = URLRequest(url: url) + request.setValue("application/json", + forHTTPHeaderField: "Content-Type") + request.setValue(accessToken, + forHTTPHeaderField: "Authorization") + + let (data, response) = try await session.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw NetworkError.networkError + } + + print("Response Status Code: \(httpResponse.statusCode)") + print("Response Headers: \(httpResponse.allHeaderFields)") + + guard (200..<300).contains(httpResponse.statusCode) else { + throw NetworkError.invalidResponse + } + + do { + let result = try JSONDecoder().decode(DailyMissionData.self, from: data) + guard let responseData = result.data else { + throw NetworkError.dataParsingError + } + return responseData + } catch { + throw NetworkError.dataParsingError + } + } + + private func patchUpdateMission(from url: URL, id: Int, requestData: String) async throws { + var request = URLRequest(url: url) + request.httpMethod = "PATCH" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + request.setValue(accessToken, forHTTPHeaderField: "Authorization") + + do { + let body = ["completionStatus": requestData] + request.httpBody = try JSONSerialization.data(withJSONObject: body) + + if let bodyData = request.httpBody, let bodyString = String(data: bodyData, encoding: .utf8) { + print("Request Body: \(bodyString)") + } else { + print("Request Body is empty or cannot be converted to String.") + } + } catch { + print("Encoding Failed: \(error)") + throw NetworkError.encodingFailed + } + + do { + let (data, response) = try await session.data(for: request) + guard let httpResponse = response as? HTTPURLResponse else { + print("Invalid response received") + throw NetworkError.networkError + } + + print("Response Status Code: \(httpResponse.statusCode)") + print("Response Headers: \(httpResponse.allHeaderFields)") + + if (200..<300).contains(httpResponse.statusCode) { + if let responseString = String(data: data, encoding: .utf8) { + print("Response Data: \(responseString)") + } else { + print("Response data is not a valid string.") + } + do { + let result = try JSONDecoder().decode(UpdateMissionStatus.self, from: data) + guard let responseData = result.data else { + print("Data Parsing Error: \(String(data: data, encoding: .utf8) ?? "No data")") + throw NetworkError.dataParsingError + } + print("Response Data: \(responseData)") + } catch { + print("Data Parsing Error: \(error)") + throw NetworkError.dataParsingError + } + } else { + print("Invalid response status code: \(httpResponse.statusCode)") + throw NetworkError.invalidResponse + } + } catch { + print("Network Request Failed: \(error)") + throw NetworkError.networkError + } + } + + private func generateURL(constant: String, parameter: String = "") -> URL { + let baseURL = Bundle.main.baseURL + let url = baseURL + constant + "/\(parameter)" + print(url) + return URL(string: url)! + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Provider/MissionProvider.swift b/iOS-NOTTODO/Widget-NOTTODO/Provider/MissionProvider.swift new file mode 100644 index 00000000..9bf53dd6 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Provider/MissionProvider.swift @@ -0,0 +1,61 @@ +// +// MissionProvider.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 5/11/24. +// + +import SwiftUI +import WidgetKit + +struct Provider: AppIntentTimelineProvider { + @AppStorage("dailyMission", store: UserDefaults.shared) var sharedData: Data = Data() + @AppStorage("quote", store: UserDefaults.shared) var quote: String = "" + + func placeholder(in context: Context) -> SimpleEntry { + SimpleEntry(todayMission: [], quote: quote) + } + + func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry { + do { + try await getQuote() + } catch { + return SimpleEntry(todayMission: [], quote: "") + } + return SimpleEntry(todayMission: [], quote: quote) + } + + func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline { + do { + let now = Date() + let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: now) ?? now + let midnightTomorrow = Calendar.current.startOfDay(for: tomorrow) + let midnightToday = Calendar.current.startOfDay(for: now) + + if now == midnightToday { + try await getQuote() + try await getDailyMission(date: Formatter.dateFormatterString(format: nil, date: now)) + } + + guard let decodedData = try? JSONDecoder().decode([DailyMissionResponseDTO].self, from: sharedData) else { + return Timeline(entries: [], policy: .never) + } + + let entry = SimpleEntry(todayMission: decodedData, quote: quote) + return Timeline(entries: [entry], policy: .after(midnightTomorrow)) + } catch { + return Timeline(entries: [], policy: .never) + } + + } + + private func getQuote() async throws { + let quoteResponse = try await WidgetService.shared.fetchWiseSaying() + quote = quoteResponse.description + " - " + quoteResponse.author + } + + private func getDailyMission(date: String) async throws { + let dailyMission = try await WidgetService.shared.fetchDailyMissoin(date: date) + UserDefaults.shared?.setSharedCustomArray(dailyMission, forKey: "dailyMission") + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Provider/TimeEntity.swift b/iOS-NOTTODO/Widget-NOTTODO/Provider/TimeEntity.swift new file mode 100644 index 00000000..cfbe563b --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Provider/TimeEntity.swift @@ -0,0 +1,18 @@ +// +// TimeEntity.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 5/11/24. +// + +import WidgetKit + +struct SimpleEntry: TimelineEntry { + var date: Date = .now + + var dayOfWeek: String { + return Formatter.dateFormatterString(format: "E", date: date) + } + var todayMission: [DailyMissionResponseDTO] + let quote: String +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/AccentColor.colorset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..13613e3e --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/WidgetBackground.colorset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/WidgetBackground.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/WidgetBackground.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/Contents.json new file mode 100644 index 00000000..f453598f --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/Contents.json @@ -0,0 +1,32 @@ +{ + "images" : [ + { + "filename" : "btn_medium 1.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "filename" : "btn_medium.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "btn_medium_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium 1.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium 1.svg new file mode 100644 index 00000000..926e54dd --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium 1.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium.svg new file mode 100644 index 00000000..926e54dd --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium_dark.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium_dark.svg new file mode 100644 index 00000000..5643f511 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium.imageset/btn_medium_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/Contents.json new file mode 100644 index 00000000..85fa1aec --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/Contents.json @@ -0,0 +1,32 @@ +{ + "images" : [ + { + "filename" : "btn_medium_fill 1.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "filename" : "btn_medium_fill.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "btn_medium_fill_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill 1.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill 1.svg new file mode 100644 index 00000000..fd10e474 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill 1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill.svg new file mode 100644 index 00000000..fd10e474 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill_dark.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill_dark.svg new file mode 100644 index 00000000..39c23f19 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_medium_fill.imageset/btn_medium_fill_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box.imageset/Contents.json new file mode 100644 index 00000000..933eda4b --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "btn_small_box.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box.imageset/btn_small_box.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box.imageset/btn_small_box.svg new file mode 100644 index 00000000..b22a4302 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box.imageset/btn_small_box.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box_fill.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box_fill.imageset/Contents.json new file mode 100644 index 00000000..123956be --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box_fill.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "btn_small_box_fill.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box_fill.imageset/btn_small_box_fill.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box_fill.imageset/btn_small_box_fill.svg new file mode 100644 index 00000000..9f2491ba --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/btn_small_box_fill.imageset/btn_small_box_fill.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_fill.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_fill.imageset/Contents.json new file mode 100644 index 00000000..2ddabd7b --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_fill.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "gage_medium_fill.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_fill.imageset/gage_medium_fill.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_fill.imageset/gage_medium_fill.svg new file mode 100644 index 00000000..482c97dc --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_fill.imageset/gage_medium_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_half.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_half.imageset/Contents.json new file mode 100644 index 00000000..558e7d91 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_half.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "gage_medium_half.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_half.imageset/gage_medium_half.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_half.imageset/gage_medium_half.svg new file mode 100644 index 00000000..a4a64187 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_half.imageset/gage_medium_half.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_zero.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_zero.imageset/Contents.json new file mode 100644 index 00000000..f94f324b --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_zero.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "gage_medium_zero.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_zero.imageset/gage_medium_zero.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_zero.imageset/gage_medium_zero.svg new file mode 100644 index 00000000..34033097 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_medium_zero.imageset/gage_medium_zero.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_fill.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_fill.imageset/Contents.json new file mode 100644 index 00000000..db096772 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_fill.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "gage_small_fill.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_fill.imageset/gage_small_fill.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_fill.imageset/gage_small_fill.svg new file mode 100644 index 00000000..d181c1a2 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_fill.imageset/gage_small_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_half.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_half.imageset/Contents.json new file mode 100644 index 00000000..68589657 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_half.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "gage_small_half.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_half.imageset/gage_small_half.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_half.imageset/gage_small_half.svg new file mode 100644 index 00000000..276ce1b9 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_half.imageset/gage_small_half.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_zero.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_zero.imageset/Contents.json new file mode 100644 index 00000000..0d412f5a --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_zero.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "gage_small_zero.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_zero.imageset/gage_small_zero.png b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_zero.imageset/gage_small_zero.png new file mode 100644 index 00000000..59780a05 Binary files /dev/null and b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/gage_small_zero.imageset/gage_small_zero.png differ diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/Contents.json new file mode 100644 index 00000000..6be24e29 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/Contents.json @@ -0,0 +1,32 @@ +{ + "images" : [ + { + "filename" : "ic_plus.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "filename" : "ic_plus 1.svg", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "ic_plus_darkmode.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus 1.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus 1.svg new file mode 100644 index 00000000..7a128d9c --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus 1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus.svg new file mode 100644 index 00000000..7a128d9c --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus_darkmode.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus_darkmode.svg new file mode 100644 index 00000000..46002197 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus.imageset/ic_plus_darkmode.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus_dark.imageset/Contents.json b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus_dark.imageset/Contents.json new file mode 100644 index 00000000..02e7623a --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus_dark.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ic_plus_dark.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus_dark.imageset/ic_plus_dark.svg b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus_dark.imageset/ic_plus_dark.svg new file mode 100644 index 00000000..7a128d9c --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Assets.xcassets/ic_plus_dark.imageset/ic_plus_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Resource/Info.plist b/iOS-NOTTODO/Widget-NOTTODO/Resource/Info.plist new file mode 100644 index 00000000..3351d0ff --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Resource/Info.plist @@ -0,0 +1,20 @@ + + + + + NSExtension + + NSExtensionAttributes + + IntentsSupported + + ConfigurationAppIntent + ToggleButtonIntent + + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/View/Common/Components/CircularProgressBar.swift b/iOS-NOTTODO/Widget-NOTTODO/View/Common/Components/CircularProgressBar.swift new file mode 100644 index 00000000..76ea3b11 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/View/Common/Components/CircularProgressBar.swift @@ -0,0 +1,39 @@ +// +// CircularProgressBar.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 4/17/24. +// + +import WidgetKit +import SwiftUI + +struct CircularProgressBarView: View { + + @State var percent = 0.0 + var size: CGFloat + var lineWidth: CGFloat + + var body: some View { + ZStack { + Circle() + .stroke(lineWidth: lineWidth) + .frame(width: size, height: size) + .foregroundColor(.gray3) + + Circle() + .trim(from: 0, to: 0 < percent && percent < 1 ? 0.5 : percent) + .stroke(style: StrokeStyle(lineWidth: lineWidth, lineCap: .butt)) + .frame(width: size, height: size) + .foregroundColor(.green2) + .rotationEffect(.degrees(-90)) + .scaleEffect(x: -1) + } + } +} + +#Preview(as: .systemSmall) { + Widget_NOTTODO() +} timeline: { + SimpleEntry(todayMission: [], quote: "") +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/View/Common/Components/HorizontalDivider.swift b/iOS-NOTTODO/Widget-NOTTODO/View/Common/Components/HorizontalDivider.swift new file mode 100644 index 00000000..4263cd3c --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/View/Common/Components/HorizontalDivider.swift @@ -0,0 +1,24 @@ +// +// HorizontalDivider.swift +// Widget-NOTTODOExtension +// +// Created by 강윤서 on 4/19/24. +// + +import SwiftUI + +struct HorizontalDivider: View { + + let color: Color + let height: CGFloat + + init(color: Color, height: CGFloat = 1) { + self.color = color + self.height = height + } + + var body: some View { + color + .frame(height: height) + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/View/MediumFamily.swift b/iOS-NOTTODO/Widget-NOTTODO/View/MediumFamily.swift new file mode 100644 index 00000000..dab04b4c --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/View/MediumFamily.swift @@ -0,0 +1,86 @@ +// +// MediumFamily.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 4/19/24. +// + +import SwiftUI +import WidgetKit + +struct MediumFamily: View { + var entry: Provider.Entry + + var body: some View { + let progressPercent = Double(entry.todayMission.filter { $0.completionStatus == .CHECKED }.count) / Double(entry.todayMission.count) + HStack { + VStack { + ZStack { + Text(entry.dayOfWeek) + .foregroundStyle(entry.dayOfWeek == "일" ? .wdgRed : .ntdBlack) + .font(.custom("Pretendard", size: 18)) + .fontWeight(.semibold) + CircularProgressBarView(percent: progressPercent, size: 42, lineWidth: 4.34)} + Spacer() + } + .padding(.top, 14) + .padding(.leading, 17) + + VStack { + Text(entry.quote) + .foregroundStyle(.gray3) + .font(.custom("Pretendard", size: 10)) + .fontWeight(.regular) + .lineLimit(2) + .padding(.horizontal, 12) + .padding(.top, 18) + .frame(maxWidth: .infinity, maxHeight: 51, alignment: .leading) + + HorizontalDivider(color: .gray5) + .padding(.top, 6) + + VStack(spacing: 9) { + if entry.todayMission.isEmpty { + Button(action: { + print("앱으로 이동") + }, label: { + Image(.icPlusDark) + .imageScale(.large) + }) + .buttonStyle(.plain) + .position(x: 10, y: 9) + } else { + ForEach(entry.todayMission) { task in + HStack { + Button(intent: ToggleButtonIntent(id: task.id, status: task.completionStatus.rawValue)) { + Image(task.completionStatus == .CHECKED ? .btnMediumFill : .btnMedium) + } + .buttonStyle(.plain) + .frame(width: 19, height: 19) + + Text(task.title) + .foregroundStyle(task.completionStatus == .CHECKED ? .gray4 : .ntdBlack) + .strikethrough(task.completionStatus == .CHECKED, color: .gray4) + .font(.custom("Pretendard-Regular", size: 11)) + .fontWeight(.regular) + Spacer() + } + .padding(.leading, 16) + .frame(height: 20) + } + } + } + + Spacer() + } + .padding(.trailing, 22) + } + .background(.white) + } +} + +#Preview(as: .systemMedium) { + Widget_NOTTODO() +} timeline: { + SimpleEntry(todayMission: [], quote: "") +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/View/SmallFamily.swift b/iOS-NOTTODO/Widget-NOTTODO/View/SmallFamily.swift new file mode 100644 index 00000000..bb9eedcd --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/View/SmallFamily.swift @@ -0,0 +1,79 @@ +// +// SmallFamily.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 4/19/24. +// + +import SwiftUI +import WidgetKit + +struct SmallFamily: View { + var entry: Provider.Entry + + var body: some View { + let progressPercent = Double(entry.todayMission.filter { $0.completionStatus == .CHECKED }.count) / Double(entry.todayMission.count) + + VStack { + HStack { + Spacer() + + ZStack { + Text(entry.dayOfWeek) + .foregroundStyle(entry.dayOfWeek == "일" ? .wdgRed : .white) + .font(.custom("Pretendard", size: 13)) + .fontWeight(.semibold) + + CircularProgressBarView(percent: progressPercent, size: 27, lineWidth: 3) + } + + Text(entry.quote) + .foregroundStyle(.white) + .font(.custom("Pretendard", size: 7)) + .fontWeight(.regular) + .lineLimit(2) + .frame(maxWidth: .infinity, alignment: .leading) + + Spacer() + } + .frame(maxWidth: .infinity, maxHeight: 48) + .background(.ntdBlack) + + VStack(spacing: 12) { + if entry.todayMission.isEmpty { + Button(action: { + print("앱으로 이동") + }, label: { + Image(.icPlus) + .imageScale(.large) + }) + .buttonStyle(.plain) + .position(x: 17, y: 12) + } else { + ForEach(entry.todayMission) { task in + HStack { + Button(intent: ToggleButtonIntent(id: task.id, status: task.completionStatus.rawValue)) { + Image(task.completionStatus == .CHECKED ? .btnSmallBoxFill : .btnSmallBox) + } + .buttonStyle(.plain) + .frame(width: 16, height: 16) + + Text(task.title) + .foregroundStyle(task.completionStatus == .CHECKED ? .gray4 : .ntdBlack) + .strikethrough(task.completionStatus == .CHECKED, color: .gray4) + .font(.custom("Pretendard-Regular", size: 8)) + .fontWeight(.regular) + .lineLimit(2) + Spacer() + } + .padding(.leading, 16) + .frame(height: 22) + } + } + } + + Spacer() + } + .background(.bg) + } +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Widget-NOTTODOExtension.entitlements b/iOS-NOTTODO/Widget-NOTTODO/Widget-NOTTODOExtension.entitlements new file mode 100644 index 00000000..71b14c10 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Widget-NOTTODOExtension.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.nottodo.iOS-NOTTODO + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Widget-NOTTODOExtensionRelease.entitlements b/iOS-NOTTODO/Widget-NOTTODO/Widget-NOTTODOExtensionRelease.entitlements new file mode 100644 index 00000000..71b14c10 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Widget-NOTTODOExtensionRelease.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.nottodo.iOS-NOTTODO + + + diff --git a/iOS-NOTTODO/Widget-NOTTODO/Widget_NOTTODO.swift b/iOS-NOTTODO/Widget-NOTTODO/Widget_NOTTODO.swift new file mode 100644 index 00000000..c7121493 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Widget_NOTTODO.swift @@ -0,0 +1,45 @@ +// +// Widget_NOTTODO.swift +// Widget-NOTTODO +// +// Created by 강윤서 on 4/14/24. +// + +import WidgetKit +import SwiftUI + +struct Widget_NOTTODOEntryView: View { + @Environment(\.widgetFamily) var family: WidgetFamily + var entry: Provider.Entry + + @ViewBuilder + var body: some View { + switch self.family { + case .systemSmall: + SmallFamily(entry: entry) + default: + MediumFamily(entry: entry) + } + } +} + +struct Widget_NOTTODO: Widget { + let kind: String = "Widget_NOTTODO" + + var body: some WidgetConfiguration { + AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in + Widget_NOTTODOEntryView(entry: entry) + .containerBackground(.fill.tertiary, for: .widget) + } + .configurationDisplayName("오늘의 낫투두") + .description("오늘 실천할 낫투두를 확인하고 명언을 통해 동기부여를 얻을 수 있어요") + .contentMarginsDisabled() + .supportedFamilies([.systemSmall, .systemMedium]) + } +} + +#Preview(as: .systemMedium) { + Widget_NOTTODO() +} timeline: { + SimpleEntry(todayMission: [], quote: "") +} diff --git a/iOS-NOTTODO/Widget-NOTTODO/Widget_NOTTODOBundle.swift b/iOS-NOTTODO/Widget-NOTTODO/Widget_NOTTODOBundle.swift new file mode 100644 index 00000000..42b803c1 --- /dev/null +++ b/iOS-NOTTODO/Widget-NOTTODO/Widget_NOTTODOBundle.swift @@ -0,0 +1,16 @@ +// +// Widget_NOTTODOBundle.swift +// Widget-NOTTODO +// +// Created by 강윤서 on 4/14/24. +// + +import WidgetKit +import SwiftUI + +@main +struct Widget_NOTTODOBundle: WidgetBundle { + var body: some Widget { + Widget_NOTTODO() + } +} diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj index 98448be5..4535096b 100644 --- a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj @@ -79,7 +79,6 @@ 09F6719029CB6AB400708725 /* OnboardingFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F6718F29CB6AB400708725 /* OnboardingFooterView.swift */; }; 09F6719529CBFCD200708725 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F6719429CBFCD200708725 /* GradientView.swift */; }; 09F6719729CC81B500708725 /* DetailAchievementCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F6719629CC81B500708725 /* DetailAchievementCollectionViewCell.swift */; }; - 155E45662B5FF089008628E7 /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = 155E45652B5FF089008628E7 /* FirebaseRemoteConfig */; }; 155E45692B5FF2EE008628E7 /* FirebaseUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 155E45682B5FF2EE008628E7 /* FirebaseUtil.swift */; }; 155E456D2B62B1A1008628E7 /* UpdateCheckViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 155E456C2B62B1A1008628E7 /* UpdateCheckViewController.swift */; }; 3B027A78299C31B500BEB65C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B027A77299C31B500BEB65C /* AppDelegate.swift */; }; @@ -113,7 +112,19 @@ 3B14A13F29A6FCB300F92897 /* UIStackView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B14A13E29A6FCB300F92897 /* UIStackView+.swift */; }; 3B14A14129A6FDA900F92897 /* UILabel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B14A14029A6FDA900F92897 /* UILabel+.swift */; }; 3B14A14329A6FEE400F92897 /* UITextField+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B14A14229A6FEE400F92897 /* UITextField+.swift */; }; - 3B2B59442AEB814B00B4619A /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 3B2B59432AEB814B00B4619A /* FirebaseMessaging */; }; + 3B2AA7E52BD62D1200725457 /* URLConstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4705A29A68EA9008D145C /* URLConstant.swift */; }; + 3B3105D22BCBF70600964025 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1E84932BAC897C002F9808 /* WidgetKit.framework */; }; + 3B3105D32BCBF70600964025 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1E84952BAC897C002F9808 /* SwiftUI.framework */; }; + 3B3105D62BCBF70600964025 /* Widget_NOTTODOBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3105D52BCBF70600964025 /* Widget_NOTTODOBundle.swift */; }; + 3B3105D82BCBF70600964025 /* Widget_NOTTODO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3105D72BCBF70600964025 /* Widget_NOTTODO.swift */; }; + 3B3105DA2BCBF70600964025 /* AppIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3105D92BCBF70600964025 /* AppIntent.swift */; }; + 3B3105DC2BCBF70700964025 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3B3105DB2BCBF70700964025 /* Assets.xcassets */; }; + 3B3105E02BCBF70700964025 /* Widget-NOTTODOExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 3B3105D12BCBF70600964025 /* Widget-NOTTODOExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 3B3105E92BCC00D800964025 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3B027AAB299C35E500BEB65C /* Colors.xcassets */; }; + 3B3105EB2BCC022500964025 /* UIFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B027A93299C340600BEB65C /* UIFont+.swift */; }; + 3B35F57C2BF091A60050D450 /* NetworkConstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4706029A69096008D145C /* NetworkConstant.swift */; }; + 3B35F57D2BF093120050D450 /* KeychainUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0960C0D32A38BC6500A3D8DB /* KeychainUtil.swift */; }; + 3B35F5822BF0A4770050D450 /* Formatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B35F5802BF0A36F0050D450 /* Formatter.swift */; }; 3B37AE2929C8821600AB7587 /* GoalCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B37AE2829C8821600AB7587 /* GoalCollectionViewCell.swift */; }; 3B37AE2B29C8904800AB7587 /* RecommendKeywordCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B37AE2A29C8904800AB7587 /* RecommendKeywordCollectionViewCell.swift */; }; 3B3EF2F82AF35C90001F79BC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3EF2F72AF35C90001F79BC /* GoogleService-Info.plist */; }; @@ -132,18 +143,43 @@ 3B5F8F8129BF90190063A7F8 /* NottodoCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5F8F8029BF90190063A7F8 /* NottodoCollectionViewCell.swift */; }; 3B5F8F8329BF90290063A7F8 /* SituationCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5F8F8229BF90290063A7F8 /* SituationCollectionViewCell.swift */; }; 3B5F8F8929BF9EFE0063A7F8 /* AddMissionLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5F8F8829BF9EFE0063A7F8 /* AddMissionLabel.swift */; }; + 3B706A6C2BD5746A00CD6C74 /* UserDefaults+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B706A6B2BD5746A00CD6C74 /* UserDefaults+.swift */; }; + 3B706A6D2BD5771100CD6C74 /* UserDefaults+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B706A6B2BD5746A00CD6C74 /* UserDefaults+.swift */; }; 3B710A5C2A62D4AB00E95620 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 3B710A5B2A62D4AB00E95620 /* Settings.bundle */; }; 3B80B5D52B7F304D00697250 /* adjust+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80B5D42B7F304D00697250 /* adjust+.swift */; }; 3B80B5D72B7F30E200697250 /* Numbers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B80B5D62B7F30E200697250 /* Numbers.swift */; }; 3B892ABB2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B892ABA2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift */; }; 3B9532F42A284CC1006510F8 /* ModalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B9532F32A284CC1006510F8 /* ModalProtocol.swift */; }; + 3B99131C2BF08B5B00FA9328 /* DefaultKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0960C0D52A38BC8100A3D8DB /* DefaultKeys.swift */; }; + 3B999D0C2BAEC24100E562EE /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = 3B999D0B2BAEC24100E562EE /* FirebaseRemoteConfig */; }; + 3B999D0E2BAEC24800E562EE /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 3B999D0D2BAEC24800E562EE /* FirebaseMessaging */; }; + 3BAFA50F2BCFBF1F007569DD /* Pretendard-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3B4E12F92A27C4DD001D1EC1 /* Pretendard-Bold.otf */; }; + 3BAFA5102BCFBF22007569DD /* Pretendard-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3B146D9D299D081400B17B62 /* Pretendard-SemiBold.otf */; }; + 3BAFA5112BCFBF24007569DD /* Pretendard-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3B146D9B299D07D500B17B62 /* Pretendard-Regular.otf */; }; + 3BAFA5122BCFBF26007569DD /* Pretendard-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3B146D99299D079D00B17B62 /* Pretendard-Light.otf */; }; + 3BAFA5132BCFBF29007569DD /* Pretendard-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3B146D97299D077800B17B62 /* Pretendard-Medium.otf */; }; + 3BAFA51A2BD01C2C007569DD /* CircularProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAFA5182BD01994007569DD /* CircularProgressBar.swift */; }; + 3BB5912D2BD3B103003FB77C /* API_KEY.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B570B332BA30E6100418250 /* API_KEY.plist */; }; + 3BB5912E2BD3B212003FB77C /* Bundle+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0943A9F82A53239200614761 /* Bundle+.swift */; }; + 3BB591302BD3B343003FB77C /* DailyMissionResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09DCCD1E2A18ED76003DCF8A /* DailyMissionResponseDTO.swift */; }; + 3BB5CFE52BD19639006326B5 /* SmallFamily.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB5CFE32BD19609006326B5 /* SmallFamily.swift */; }; + 3BB5CFE82BD1978E006326B5 /* MediumFamily.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB5CFE62BD1978C006326B5 /* MediumFamily.swift */; }; + 3BB5CFEC2BD1A04D006326B5 /* HorizontalDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB5CFEB2BD1A04D006326B5 /* HorizontalDivider.swift */; }; 3BBB6C8F2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BBB6C8E2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift */; }; 3BC19A9329CA1CA800C02803 /* UICollectionViewCell+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC19A9229CA1CA800C02803 /* UICollectionViewCell+.swift */; }; 3BC1A27229C9AF310088376B /* MissionHistoryModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC1A27129C9AF310088376B /* MissionHistoryModels.swift */; }; 3BC1A27429C9AF500088376B /* MissionHistoryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC1A27329C9AF500088376B /* MissionHistoryCollectionViewCell.swift */; }; 3BC1A27929C9BE6C0088376B /* AddMissionFooterCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC1A27829C9BE6C0088376B /* AddMissionFooterCollectionReusableView.swift */; }; 3BD3B5C829B8F82C00D3575B /* AddMissionTextFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BD3B5C729B8F82C00D3575B /* AddMissionTextFieldView.swift */; }; + 3BEC83AA2BEDF65000632FA0 /* GeneralResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4705E29A69025008D145C /* GeneralResponse.swift */; }; + 3BEC83AE2BEE06B900632FA0 /* QuoteResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEC83AC2BEDF73A00632FA0 /* QuoteResponseDTO.swift */; }; + 3BEC83AF2BEE06BD00632FA0 /* WidgetService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEC83A52BEDF3DE00632FA0 /* WidgetService.swift */; }; 3BEEBE972A4B048A0081C936 /* NottodoToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BEEBE962A4B048A0081C936 /* NottodoToastView.swift */; }; + 3BF8C68F2BEE6FCE0003D8FE /* NetworkResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4706229A690CD008D145C /* NetworkResult.swift */; }; + 3BF8C6912BEE70CF0003D8FE /* NetworkBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4706429A690E5008D145C /* NetworkBase.swift */; }; + 3BF8C6952BEE74A40003D8FE /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF8C6932BEE746D0003D8FE /* NetworkError.swift */; }; + 3BF8C6992BEE79830003D8FE /* TimeEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF8C6972BEE795E0003D8FE /* TimeEntity.swift */; }; + 3BF8C69C2BEE7ACF0003D8FE /* MissionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF8C69A2BEE7ABB0003D8FE /* MissionProvider.swift */; }; 6C049A312A595C670085E40B /* logo.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 6C049A302A595C670085E40B /* logo.mp4 */; }; 6C16015829C40112005AE3F5 /* AuthButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C16015729C40112005AE3F5 /* AuthButtonView.swift */; }; 6C16015C29C56DBA005AE3F5 /* MyInfoAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C16015B29C56DBA005AE3F5 /* MyInfoAccountViewController.swift */; }; @@ -187,6 +223,16 @@ 6CF4707A29A7AAFF008D145C /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4707929A7AAFF008D145C /* PaddingLabel.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 3B3105DE2BCBF70700964025 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3B027A6C299C31B500BEB65C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3B3105D02BCBF70600964025; + remoteInfo = "Widget-NOTTODOExtension"; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 3B1E84A92BAC897E002F9808 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; @@ -194,6 +240,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + 3B3105E02BCBF70700964025 /* Widget-NOTTODOExtension.appex in Embed Foundation Extensions */, ); name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -305,6 +352,13 @@ 3B14A14229A6FEE400F92897 /* UITextField+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+.swift"; sourceTree = ""; }; 3B1E84932BAC897C002F9808 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 3B1E84952BAC897C002F9808 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + 3B3105D12BCBF70600964025 /* Widget-NOTTODOExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Widget-NOTTODOExtension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3105D52BCBF70600964025 /* Widget_NOTTODOBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Widget_NOTTODOBundle.swift; sourceTree = ""; }; + 3B3105D72BCBF70600964025 /* Widget_NOTTODO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Widget_NOTTODO.swift; sourceTree = ""; }; + 3B3105D92BCBF70600964025 /* AppIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIntent.swift; sourceTree = ""; }; + 3B3105DB2BCBF70700964025 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 3B3105DD2BCBF70700964025 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3B35F5802BF0A36F0050D450 /* Formatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Formatter.swift; sourceTree = ""; }; 3B37AE2829C8821600AB7587 /* GoalCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalCollectionViewCell.swift; sourceTree = ""; }; 3B37AE2A29C8904800AB7587 /* RecommendKeywordCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendKeywordCollectionViewCell.swift; sourceTree = ""; }; 3B3EF2F72AF35C90001F79BC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -323,11 +377,19 @@ 3B5F8F8029BF90190063A7F8 /* NottodoCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NottodoCollectionViewCell.swift; sourceTree = ""; }; 3B5F8F8229BF90290063A7F8 /* SituationCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SituationCollectionViewCell.swift; sourceTree = ""; }; 3B5F8F8829BF9EFE0063A7F8 /* AddMissionLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMissionLabel.swift; sourceTree = ""; }; + 3B706A6B2BD5746A00CD6C74 /* UserDefaults+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+.swift"; sourceTree = ""; }; 3B710A5B2A62D4AB00E95620 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 3B80B5D42B7F304D00697250 /* adjust+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "adjust+.swift"; sourceTree = ""; }; 3B80B5D62B7F30E200697250 /* Numbers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Numbers.swift; sourceTree = ""; }; + 3B857AD22BD589A300CEB1D5 /* iOS-NOTTODORelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "iOS-NOTTODORelease.entitlements"; sourceTree = ""; }; + 3B857AD32BD589B700CEB1D5 /* Widget-NOTTODOExtensionRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Widget-NOTTODOExtensionRelease.entitlements"; sourceTree = ""; }; 3B892ABA2A2FBD4C00A316BC /* RecommendSituationResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendSituationResponseDTO.swift; sourceTree = ""; }; 3B9532F32A284CC1006510F8 /* ModalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalProtocol.swift; sourceTree = ""; }; + 3BAFA5182BD01994007569DD /* CircularProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularProgressBar.swift; sourceTree = ""; }; + 3BB4A51D2BD246A600900C86 /* Widget-NOTTODOExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Widget-NOTTODOExtension.entitlements"; sourceTree = ""; }; + 3BB5CFE32BD19609006326B5 /* SmallFamily.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallFamily.swift; sourceTree = ""; }; + 3BB5CFE62BD1978C006326B5 /* MediumFamily.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediumFamily.swift; sourceTree = ""; }; + 3BB5CFEB2BD1A04D006326B5 /* HorizontalDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalDivider.swift; sourceTree = ""; }; 3BBB6C8E2A1E7BEA00B8745A /* CollectionViewLeftAlignLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewLeftAlignLayout.swift; sourceTree = ""; }; 3BC19A9229CA1CA800C02803 /* UICollectionViewCell+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionViewCell+.swift"; sourceTree = ""; }; 3BC1A27129C9AF310088376B /* MissionHistoryModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MissionHistoryModels.swift; sourceTree = ""; }; @@ -335,7 +397,12 @@ 3BC1A27829C9BE6C0088376B /* AddMissionFooterCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMissionFooterCollectionReusableView.swift; sourceTree = ""; }; 3BD3B5C729B8F82C00D3575B /* AddMissionTextFieldView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMissionTextFieldView.swift; sourceTree = ""; }; 3BDE6157299EDD02001CCEA9 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; + 3BEC83A52BEDF3DE00632FA0 /* WidgetService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetService.swift; sourceTree = ""; }; + 3BEC83AC2BEDF73A00632FA0 /* QuoteResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuoteResponseDTO.swift; sourceTree = ""; }; 3BEEBE962A4B048A0081C936 /* NottodoToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NottodoToastView.swift; sourceTree = ""; }; + 3BF8C6932BEE746D0003D8FE /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = ""; }; + 3BF8C6972BEE795E0003D8FE /* TimeEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeEntity.swift; sourceTree = ""; }; + 3BF8C69A2BEE7ABB0003D8FE /* MissionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MissionProvider.swift; sourceTree = ""; }; 6C049A302A595C670085E40B /* logo.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = logo.mp4; sourceTree = ""; }; 6C16015729C40112005AE3F5 /* AuthButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthButtonView.swift; sourceTree = ""; }; 6C16015B29C56DBA005AE3F5 /* MyInfoAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyInfoAccountViewController.swift; sourceTree = ""; }; @@ -382,9 +449,9 @@ 6C44127F29A35A1000313C3F /* KakaoSDKTemplate in Frameworks */, 6C44127129A35A1000313C3F /* KakaoSDK in Frameworks */, 3B146DA4299D0A8600B17B62 /* Then in Frameworks */, + 3B999D0C2BAEC24100E562EE /* FirebaseRemoteConfig in Frameworks */, 3B146DA7299D0AA300B17B62 /* Moya in Frameworks */, - 155E45662B5FF089008628E7 /* FirebaseRemoteConfig in Frameworks */, - 3B2B59442AEB814B00B4619A /* FirebaseMessaging in Frameworks */, + 3B999D0E2BAEC24800E562EE /* FirebaseMessaging in Frameworks */, 6C44127729A35A1000313C3F /* KakaoSDKNavi in Frameworks */, 6C44128129A35A1000313C3F /* KakaoSDKUser in Frameworks */, 6C44127D29A35A1000313C3F /* KakaoSDKTalk in Frameworks */, @@ -395,6 +462,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3B3105CE2BCBF70600964025 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B3105D32BCBF70600964025 /* SwiftUI.framework in Frameworks */, + 3B3105D22BCBF70600964025 /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -728,6 +804,7 @@ 3B710A5B2A62D4AB00E95620 /* Settings.bundle */, 3BDE6157299EDD02001CCEA9 /* .swiftlint.yml */, 3B027A76299C31B500BEB65C /* iOS-NOTTODO */, + 3B3105D42BCBF70600964025 /* Widget-NOTTODO */, 3B027A75299C31B500BEB65C /* Products */, 155E45642B5FF089008628E7 /* Frameworks */, ); @@ -737,6 +814,7 @@ isa = PBXGroup; children = ( 3B027A74299C31B500BEB65C /* iOS-NOTTODO.app */, + 3B3105D12BCBF70600964025 /* Widget-NOTTODOExtension.appex */, ); name = Products; sourceTree = ""; @@ -744,6 +822,7 @@ 3B027A76299C31B500BEB65C /* iOS-NOTTODO */ = { isa = PBXGroup; children = ( + 3B857AD22BD589A300CEB1D5 /* iOS-NOTTODORelease.entitlements */, 6CF4705829A60A79008D145C /* iOS-NOTTODO.entitlements */, 0989042D2B81BB22004AAD3C /* Coordinator */, 3B027A8B299C335E00BEB65C /* Application */, @@ -795,6 +874,7 @@ 0943A9F82A53239200614761 /* Bundle+.swift */, 3B03D0D72B0F5EF300302872 /* CGSize+.swift */, 3B80B5D42B7F304D00697250 /* adjust+.swift */, + 3B706A6B2BD5746A00CD6C74 /* UserDefaults+.swift */, ); path = Extensions; sourceTree = ""; @@ -965,6 +1045,56 @@ path = ViewControllers; sourceTree = ""; }; + 3B3105D42BCBF70600964025 /* Widget-NOTTODO */ = { + isa = PBXGroup; + children = ( + 3B35F57E2BF0A34D0050D450 /* Global */, + 3BF8C6962BEE79510003D8FE /* Provider */, + 3BEC83A32BEDF3BF00632FA0 /* Network */, + 3BB4A51D2BD246A600900C86 /* Widget-NOTTODOExtension.entitlements */, + 3B857AD32BD589B700CEB1D5 /* Widget-NOTTODOExtensionRelease.entitlements */, + 3BB5CFE22BD195FA006326B5 /* View */, + 3BAFA5142BCFC5F4007569DD /* Resource */, + 3B3105D52BCBF70600964025 /* Widget_NOTTODOBundle.swift */, + 3B3105D72BCBF70600964025 /* Widget_NOTTODO.swift */, + 3B3105D92BCBF70600964025 /* AppIntent.swift */, + ); + path = "Widget-NOTTODO"; + sourceTree = ""; + }; + 3B3105EE2BCC16FA00964025 /* Common */ = { + isa = PBXGroup; + children = ( + 3B3105EF2BCC173200964025 /* Components */, + ); + path = Common; + sourceTree = ""; + }; + 3B3105EF2BCC173200964025 /* Components */ = { + isa = PBXGroup; + children = ( + 3BAFA5182BD01994007569DD /* CircularProgressBar.swift */, + 3BB5CFEB2BD1A04D006326B5 /* HorizontalDivider.swift */, + ); + path = Components; + sourceTree = ""; + }; + 3B35F57E2BF0A34D0050D450 /* Global */ = { + isa = PBXGroup; + children = ( + 3B35F57F2BF0A3610050D450 /* Extensions */, + ); + path = Global; + sourceTree = ""; + }; + 3B35F57F2BF0A3610050D450 /* Extensions */ = { + isa = PBXGroup; + children = ( + 3B35F5802BF0A36F0050D450 /* Formatter.swift */, + ); + path = Extensions; + sourceTree = ""; + }; 3B3C89DB29C0EF6A00B1D56D /* Models */ = { isa = PBXGroup; children = ( @@ -1102,6 +1232,25 @@ path = Protocol; sourceTree = ""; }; + 3BAFA5142BCFC5F4007569DD /* Resource */ = { + isa = PBXGroup; + children = ( + 3B3105DB2BCBF70700964025 /* Assets.xcassets */, + 3B3105DD2BCBF70700964025 /* Info.plist */, + ); + path = Resource; + sourceTree = ""; + }; + 3BB5CFE22BD195FA006326B5 /* View */ = { + isa = PBXGroup; + children = ( + 3B3105EE2BCC16FA00964025 /* Common */, + 3BB5CFE32BD19609006326B5 /* SmallFamily.swift */, + 3BB5CFE62BD1978C006326B5 /* MediumFamily.swift */, + ); + path = View; + sourceTree = ""; + }; 3BD3B5C629B8F80C00D3575B /* AddMissionTextFieldView */ = { isa = PBXGroup; children = ( @@ -1110,6 +1259,32 @@ path = AddMissionTextFieldView; sourceTree = ""; }; + 3BEC83A32BEDF3BF00632FA0 /* Network */ = { + isa = PBXGroup; + children = ( + 3BF8C6922BEE744D0003D8FE /* Base */, + 3BEC83AB2BEDF71A00632FA0 /* DataModel */, + 3BEC83A42BEDF3D100632FA0 /* Service */, + ); + path = Network; + sourceTree = ""; + }; + 3BEC83A42BEDF3D100632FA0 /* Service */ = { + isa = PBXGroup; + children = ( + 3BEC83A52BEDF3DE00632FA0 /* WidgetService.swift */, + ); + path = Service; + sourceTree = ""; + }; + 3BEC83AB2BEDF71A00632FA0 /* DataModel */ = { + isa = PBXGroup; + children = ( + 3BEC83AC2BEDF73A00632FA0 /* QuoteResponseDTO.swift */, + ); + path = DataModel; + sourceTree = ""; + }; 3BEEBE952A4AF6840081C936 /* Toast */ = { isa = PBXGroup; children = ( @@ -1118,6 +1293,23 @@ path = Toast; sourceTree = ""; }; + 3BF8C6922BEE744D0003D8FE /* Base */ = { + isa = PBXGroup; + children = ( + 3BF8C6932BEE746D0003D8FE /* NetworkError.swift */, + ); + path = Base; + sourceTree = ""; + }; + 3BF8C6962BEE79510003D8FE /* Provider */ = { + isa = PBXGroup; + children = ( + 3BF8C6972BEE795E0003D8FE /* TimeEntity.swift */, + 3BF8C69A2BEE7ABB0003D8FE /* MissionProvider.swift */, + ); + path = Provider; + sourceTree = ""; + }; 6C16015929C56CE8005AE3F5 /* MyInfoAccount */ = { isa = PBXGroup; children = ( @@ -1267,6 +1459,7 @@ buildRules = ( ); dependencies = ( + 3B3105DF2BCBF70700964025 /* PBXTargetDependency */, ); name = "iOS-NOTTODO"; packageProductDependencies = ( @@ -1285,13 +1478,30 @@ 6C9628A62A22208F003ADE25 /* Lottie */, 0943A9F42A531D0000614761 /* Amplitude */, 09C8602C2AB14B4800C4F4B1 /* FSCalendar */, - 3B2B59432AEB814B00B4619A /* FirebaseMessaging */, - 155E45652B5FF089008628E7 /* FirebaseRemoteConfig */, + 3B999D0B2BAEC24100E562EE /* FirebaseRemoteConfig */, + 3B999D0D2BAEC24800E562EE /* FirebaseMessaging */, ); productName = "iOS-NOTTODO"; productReference = 3B027A74299C31B500BEB65C /* iOS-NOTTODO.app */; productType = "com.apple.product-type.application"; }; + 3B3105D02BCBF70600964025 /* Widget-NOTTODOExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3B3105E32BCBF70700964025 /* Build configuration list for PBXNativeTarget "Widget-NOTTODOExtension" */; + buildPhases = ( + 3B3105CD2BCBF70600964025 /* Sources */, + 3B3105CE2BCBF70600964025 /* Frameworks */, + 3B3105CF2BCBF70600964025 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Widget-NOTTODOExtension"; + productName = "Widget-NOTTODOExtension"; + productReference = 3B3105D12BCBF70600964025 /* Widget-NOTTODOExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1299,12 +1509,15 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1530; + LastSwiftUpdateCheck = 1520; LastUpgradeCheck = 1420; TargetAttributes = { 3B027A73299C31B500BEB65C = { CreatedOnToolsVersion = 14.2; }; + 3B3105D02BCBF70600964025 = { + CreatedOnToolsVersion = 15.2; + }; }; }; buildConfigurationList = 3B027A6F299C31B500BEB65C /* Build configuration list for PBXProject "iOS-NOTTODO" */; @@ -1325,13 +1538,14 @@ 6C9628A52A22208F003ADE25 /* XCRemoteSwiftPackageReference "lottie-ios" */, 0943A9F32A531D0000614761 /* XCRemoteSwiftPackageReference "Amplitude-iOS" */, 09C8602B2AB14B4700C4F4B1 /* XCRemoteSwiftPackageReference "FSCalendar" */, - 3B2B59422AEB814B00B4619A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, + 3B999D0A2BAEC1F100E562EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, ); productRefGroup = 3B027A75299C31B500BEB65C /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 3B027A73299C31B500BEB65C /* iOS-NOTTODO */, + 3B3105D02BCBF70600964025 /* Widget-NOTTODOExtension */, ); }; /* End PBXProject section */ @@ -1357,6 +1571,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3B3105CF2BCBF70600964025 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B3105DC2BCBF70700964025 /* Assets.xcassets in Resources */, + 3BB5912D2BD3B103003FB77C /* API_KEY.plist in Resources */, + 3BAFA5112BCFBF24007569DD /* Pretendard-Regular.otf in Resources */, + 3BAFA50F2BCFBF1F007569DD /* Pretendard-Bold.otf in Resources */, + 3BAFA5132BCFBF29007569DD /* Pretendard-Medium.otf in Resources */, + 3BAFA5102BCFBF22007569DD /* Pretendard-SemiBold.otf in Resources */, + 3BAFA5122BCFBF26007569DD /* Pretendard-Light.otf in Resources */, + 3B3105E92BCC00D800964025 /* Colors.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -1483,6 +1712,7 @@ 3BC1A27229C9AF310088376B /* MissionHistoryModels.swift in Sources */, 6CD4F8BA29AA493600CCC740 /* RecommendActionHeaderView.swift in Sources */, 0930DE6229B80550007958DE /* MissionDetailViewController.swift in Sources */, + 3B706A6C2BD5746A00CD6C74 /* UserDefaults+.swift in Sources */, 0989044C2B81C210004AAD3C /* HomecoordinatorImpl.swift in Sources */, 3B14A13F29A6FCB300F92897 /* UIStackView+.swift in Sources */, 6CD4F8BC29AA494300CCC740 /* RecommendActionFooterView.swift in Sources */, @@ -1537,8 +1767,47 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3B3105CD2BCBF70600964025 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3BB5CFE82BD1978E006326B5 /* MediumFamily.swift in Sources */, + 3B3105D62BCBF70600964025 /* Widget_NOTTODOBundle.swift in Sources */, + 3BB591302BD3B343003FB77C /* DailyMissionResponseDTO.swift in Sources */, + 3B706A6D2BD5771100CD6C74 /* UserDefaults+.swift in Sources */, + 3B2AA7E52BD62D1200725457 /* URLConstant.swift in Sources */, + 3B3105EB2BCC022500964025 /* UIFont+.swift in Sources */, + 3B35F5822BF0A4770050D450 /* Formatter.swift in Sources */, + 3B3105D82BCBF70600964025 /* Widget_NOTTODO.swift in Sources */, + 3BF8C68F2BEE6FCE0003D8FE /* NetworkResult.swift in Sources */, + 3B99131C2BF08B5B00FA9328 /* DefaultKeys.swift in Sources */, + 3BF8C6912BEE70CF0003D8FE /* NetworkBase.swift in Sources */, + 3BB5CFEC2BD1A04D006326B5 /* HorizontalDivider.swift in Sources */, + 3BB5912E2BD3B212003FB77C /* Bundle+.swift in Sources */, + 3BAFA51A2BD01C2C007569DD /* CircularProgressBar.swift in Sources */, + 3BEC83AA2BEDF65000632FA0 /* GeneralResponse.swift in Sources */, + 3B3105DA2BCBF70600964025 /* AppIntent.swift in Sources */, + 3BF8C6992BEE79830003D8FE /* TimeEntity.swift in Sources */, + 3BEC83AF2BEE06BD00632FA0 /* WidgetService.swift in Sources */, + 3BF8C6952BEE74A40003D8FE /* NetworkError.swift in Sources */, + 3B35F57C2BF091A60050D450 /* NetworkConstant.swift in Sources */, + 3B35F57D2BF093120050D450 /* KeychainUtil.swift in Sources */, + 3BF8C69C2BEE7ACF0003D8FE /* MissionProvider.swift in Sources */, + 3BB5CFE52BD19639006326B5 /* SmallFamily.swift in Sources */, + 3BEC83AE2BEE06B900632FA0 /* QuoteResponseDTO.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 3B3105DF2BCBF70700964025 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3B3105D02BCBF70600964025 /* Widget-NOTTODOExtension */; + targetProxy = 3B3105DE2BCBF70700964025 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 3B027A82299C31B600BEB65C /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; @@ -1668,6 +1937,7 @@ 3B027A89299C31B600BEB65C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "iOS-NOTTODO/iOS-NOTTODO.entitlements"; @@ -1689,7 +1959,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.4; + MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1706,9 +1976,10 @@ 3B027A8A299C31B600BEB65C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = "iOS-NOTTODO/iOS-NOTTODO.entitlements"; + CODE_SIGN_ENTITLEMENTS = "iOS-NOTTODO/iOS-NOTTODORelease.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; @@ -1727,7 +1998,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.4; + MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1741,6 +2012,83 @@ }; name = Release; }; + 3B3105E12BCBF70700964025 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = "Widget-NOTTODO/Widget-NOTTODOExtension.entitlements"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CQJ9UKUU35; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Widget-NOTTODO/Resource/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "Widget-NOTTODO"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO.Widget-NOTTODO"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = nottodoWidgetDebug; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 3B3105E22BCBF70700964025 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = "Widget-NOTTODO/Widget-NOTTODOExtensionRelease.entitlements"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CQJ9UKUU35; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Widget-NOTTODO/Resource/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "Widget-NOTTODO"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO.Widget-NOTTODO"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = nottodoWidgetRelease; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1762,6 +2110,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 3B3105E32BCBF70700964025 /* Build configuration list for PBXNativeTarget "Widget-NOTTODOExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3B3105E12BCBF70700964025 /* Debug */, + 3B3105E22BCBF70700964025 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -1805,20 +2162,21 @@ kind = branch; }; }; - 3B2B59422AEB814B00B4619A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + 3B999D0A2BAEC1F100E562EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 10.0.0; + minimumVersion = 10.23.0; }; }; 6C44126F29A35A1000313C3F /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kakao/kakao-ios-sdk"; requirement = { - branch = master; - kind = branch; + kind = versionRange; + maximumVersion = 2.21.1; + minimumVersion = 2.21.1; }; }; 6C9628A52A22208F003ADE25 /* XCRemoteSwiftPackageReference "lottie-ios" */ = { @@ -1850,11 +2208,6 @@ package = 09C8602B2AB14B4700C4F4B1 /* XCRemoteSwiftPackageReference "FSCalendar" */; productName = FSCalendar; }; - 155E45652B5FF089008628E7 /* FirebaseRemoteConfig */ = { - isa = XCSwiftPackageProductDependency; - package = 3B2B59422AEB814B00B4619A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseRemoteConfig; - }; 3B146DA0299D0A7A00B17B62 /* SnapKit */ = { isa = XCSwiftPackageProductDependency; package = 3B146D9F299D0A7A00B17B62 /* XCRemoteSwiftPackageReference "SnapKit" */; @@ -1870,9 +2223,14 @@ package = 3B146DA5299D0AA300B17B62 /* XCRemoteSwiftPackageReference "Moya" */; productName = Moya; }; - 3B2B59432AEB814B00B4619A /* FirebaseMessaging */ = { + 3B999D0B2BAEC24100E562EE /* FirebaseRemoteConfig */ = { + isa = XCSwiftPackageProductDependency; + package = 3B999D0A2BAEC1F100E562EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseRemoteConfig; + }; + 3B999D0D2BAEC24800E562EE /* FirebaseMessaging */ = { isa = XCSwiftPackageProductDependency; - package = 3B2B59422AEB814B00B4619A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + package = 3B999D0A2BAEC1F100E562EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseMessaging; }; 6C44127029A35A1000313C3F /* KakaoSDK */ = { diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/xcshareddata/xcschemes/Widget-NOTTODOExtension.xcscheme b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/xcshareddata/xcschemes/Widget-NOTTODOExtension.xcscheme new file mode 100644 index 00000000..353d816a --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/xcshareddata/xcschemes/Widget-NOTTODOExtension.xcscheme @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Enum/KeychainUtil.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Enum/KeychainUtil.swift index 82c40c0d..0633a7aa 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Global/Enum/KeychainUtil.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Enum/KeychainUtil.swift @@ -14,6 +14,7 @@ public final class KeychainUtil { } static func setAccessToken(_ token: String) { UserDefaults.standard.setValue(token, forKey: DefaultKeys.accessToken) + UserDefaults.shared?.setValue(token, forKey: DefaultKeys.accessToken) } static func setFcmToken(_ token: String) { UserDefaults.standard.setValue(token, forKey: DefaultKeys.fcmToken) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift index d752fe1d..b949a454 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift @@ -56,4 +56,17 @@ extension Bundle { } return value } + + var appGroups: String { + guard let filePath = Bundle.main.path(forResource: "API_KEY", ofType: "plist") else { + fatalError("Could't find file 'API_KEY.plist'.") + } + + let plist = NSDictionary(contentsOfFile: filePath) + + guard let value = plist?.object(forKey: "APP_GROUPS") as? String else { + fatalError("Couldn't find key 'APP_GROUPS' in 'API_KEY.plist'.") + } + return value + } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Design/UIColor+.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Design/UIColor+.swift index b2a316ea..d7c3b96d 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Design/UIColor+.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Design/UIColor+.swift @@ -9,9 +9,9 @@ import UIKit extension UIColor { static let bg = UIColor(named: "bg") - static let ntdBlack = UIColor(named: "black") - static let ntdBlue = UIColor(named: "blue") - static let ntdRed = UIColor(named: "red") + static let ntdBlack = UIColor(named: "ntdBlack") + static let ntdBlue = UIColor(named: "ntdBlue") + static let ntdRed = UIColor(named: "ntdRed") static let gray1 = UIColor(named: "gray1") static let gray2 = UIColor(named: "gray2") static let gray3 = UIColor(named: "gray3") @@ -23,7 +23,7 @@ extension UIColor { static let green1 = UIColor(named: "green1") static let green2 = UIColor(named: "green2") static let systemBlack = UIColor(named: "systemBlack") - static let kakaoYellow = UIColor(named: "yellow") + static let kakaoYellow = UIColor(named: "ntdYellow") static let notiBlack = UIColor(named: "notiBlack") static let notiGreen = UIColor(named: "notiGreen") static let notiBlue = UIColor(named: "notiBlue") diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UserDefaults+.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UserDefaults+.swift new file mode 100644 index 00000000..8034788f --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/UserDefaults+.swift @@ -0,0 +1,31 @@ +// +// UserDefaults+.swift +// iOS-NOTTODO +// +// Created by 강윤서 on 4/22/24. +// + +import Foundation +import WidgetKit + +extension UserDefaults { + static var shared: UserDefaults? { + return UserDefaults(suiteName: Bundle.main.appGroups) + } + + func setSharedCustomArray(_ value: [T], forKey key: String) { + if let encoded = try? JSONEncoder().encode(value) { + self.set(encoded, forKey: key) + } + WidgetCenter.shared.reloadAllTimelines() + } + + func getSharedCustomArray(forKey key: String) -> [T]? { + if let savedData = self.object(forKey: key) as? Data { + if let savedObject = try? JSONDecoder().decode([T].self, from: savedData) { + return savedObject + } + } + return nil + } +} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Network/Base/URLConstant.swift b/iOS-NOTTODO/iOS-NOTTODO/Network/Base/URLConstant.swift index a48b56ee..e59dea9c 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Network/Base/URLConstant.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Network/Base/URLConstant.swift @@ -34,4 +34,8 @@ struct URLConstant { // MARK: - AddMission static let recentMission = "/recent" + + // MARK: - Widget + + static let quote = "/quote/random" } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Network/DataModel/Home/DailyMissionResponseDTO.swift b/iOS-NOTTODO/iOS-NOTTODO/Network/DataModel/Home/DailyMissionResponseDTO.swift index 01d2cb30..601ea34e 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Network/DataModel/Home/DailyMissionResponseDTO.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Network/DataModel/Home/DailyMissionResponseDTO.swift @@ -13,16 +13,17 @@ enum CompletionStatus: String, Codable, Hashable { // MARK: - DailyMissionResponseDTO -struct DailyMissionResponseDTO: Codable, Hashable { +struct DailyMissionResponseDTO: Codable, Hashable, Identifiable { var uuid = UUID() let id: Int let title: String let situationName: String let completionStatus: CompletionStatus + let date: String enum CodingKeys: String, CodingKey { - case id, title, situationName, completionStatus + case id, title, situationName, completionStatus, date } static func == (lhs: DailyMissionResponseDTO, rhs: DailyMissionResponseDTO) -> Bool { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Network/Service/BaseAPI.swift b/iOS-NOTTODO/iOS-NOTTODO/Network/Service/BaseAPI.swift index 239fa320..05a6a339 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Network/Service/BaseAPI.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Network/Service/BaseAPI.swift @@ -60,10 +60,9 @@ public enum HeaderType { public var value: [String: String] { switch self { case .json: - return ["Content-Type": "application/json"] + return NetworkConstant.noTokenHeader case .jsonWithToken: - return ["Content-Type": "application/json", - "Authorization": "\(KeychainUtil.getAccessToken())"] + return NetworkConstant.hasTokenHeader } } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Network/Service/Recommend/RecommendService.swift b/iOS-NOTTODO/iOS-NOTTODO/Network/Service/Recommend/RecommendService.swift index c98b7c92..d12d240a 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Network/Service/Recommend/RecommendService.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Network/Service/Recommend/RecommendService.swift @@ -46,7 +46,7 @@ final class RecommendService: RecommendServiceType { } } - func getRecommendAction(index: Int, completion: @escaping (GeneralResponse?) -> Void) { + func getRecommendAction(index: Int, completion: @escaping (ActionData?) -> Void) { provider.request(.action(id: index)) { result in switch result { case .success(let response): diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeDataSource.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeDataSource.swift index 9f7e40f6..07207c14 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeDataSource.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeDataSource.swift @@ -130,6 +130,12 @@ final class HomeDataSource { currentSection = newSections dataSource?.apply(snapshot) + + if let firstMissionDate = missionList.first?.date, !missionList.isEmpty { + if firstMissionDate == Utils.dateFormatterString(format: nil, date: Date()) { + UserDefaults.shared?.setSharedCustomArray(missionList, forKey: "dailyMission") + } + } } private func createLayout() -> UICollectionViewLayout { diff --git a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeViewController.swift b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeViewController.swift index 60fa3a53..357982f3 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeViewController.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Presentation/Home/ViewControllers/HomeViewController.swift @@ -245,6 +245,10 @@ extension HomeViewController { self.missionList = data self.missionDataSource.updateSnapShot(missionList: data) + + if Utils.dateFormatterString(format: nil, date: today) == date && missionList.isEmpty { + UserDefaults.shared?.setSharedCustomArray(missionList, forKey: "dailyMission") + } } } @@ -317,6 +321,13 @@ extension HomeViewController { return sundayInWeek } + private func getDayOfWeek(date: Date) -> String { + let calendar = Calendar.current + let weekday = calendar.component(.weekday, from: date) + + return I18N.weekDay[weekday-1] + } + private func getPercentage(for date: Date) -> Float? { let dateString = Utils.dateFormatterString(format: nil, date: date) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/black.colorset/Contents.json b/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdBlack.colorset/Contents.json similarity index 100% rename from iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/black.colorset/Contents.json rename to iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdBlack.colorset/Contents.json diff --git a/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/blue.colorset/Contents.json b/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdBlue.colorset/Contents.json similarity index 100% rename from iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/blue.colorset/Contents.json rename to iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdBlue.colorset/Contents.json diff --git a/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/yellow.colorset/Contents.json b/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdYellow.colorset/Contents.json similarity index 100% rename from iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/yellow.colorset/Contents.json rename to iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdYellow.colorset/Contents.json diff --git a/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdred.colorset/Contents.json b/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdred.colorset/Contents.json new file mode 100644 index 00000000..84a82a56 --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/ntdred.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.392", + "green" : "0.392", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0.412", + "green" : "0.435", + "red" : "0.925" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/red.colorset/Contents.json b/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/wdgRed.colorset/Contents.json similarity index 83% rename from iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/red.colorset/Contents.json rename to iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/wdgRed.colorset/Contents.json index 41117905..ca2afcfe 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/red.colorset/Contents.json +++ b/iOS-NOTTODO/iOS-NOTTODO/Resource/Colors/Colors.xcassets/wdgRed.colorset/Contents.json @@ -5,8 +5,8 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0.392", - "green" : "0.392", + "blue" : "0.271", + "green" : "0.271", "red" : "1.000" } }, @@ -23,8 +23,8 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0.392", - "green" : "0.392", + "blue" : "0.271", + "green" : "0.271", "red" : "1.000" } }, diff --git a/iOS-NOTTODO/iOS-NOTTODO/iOS-NOTTODO.entitlements b/iOS-NOTTODO/iOS-NOTTODO/iOS-NOTTODO.entitlements index 80b5221d..10d5d8bb 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/iOS-NOTTODO.entitlements +++ b/iOS-NOTTODO/iOS-NOTTODO/iOS-NOTTODO.entitlements @@ -8,5 +8,9 @@ Default + com.apple.security.application-groups + + group.nottodo.iOS-NOTTODO + diff --git a/iOS-NOTTODO/iOS-NOTTODO/iOS-NOTTODORelease.entitlements b/iOS-NOTTODO/iOS-NOTTODO/iOS-NOTTODORelease.entitlements new file mode 100644 index 00000000..10d5d8bb --- /dev/null +++ b/iOS-NOTTODO/iOS-NOTTODO/iOS-NOTTODORelease.entitlements @@ -0,0 +1,16 @@ + + + + + aps-environment + development + com.apple.developer.applesignin + + Default + + com.apple.security.application-groups + + group.nottodo.iOS-NOTTODO + + +