Skip to content

Commit

Permalink
[Feat] #252 - 명언 api 통신 후 entry 업데이트
Browse files Browse the repository at this point in the history
- URLSession을 활용한 서버통신
- 위젯에 보여질 TimeEntry 생성
- View 내의 명언 Text 크기 및 정렬 수정
- Widget_NOTTODOEntryView에서 Provider.entry 사용으로 변경
  • Loading branch information
yungu0010 committed May 10, 2024
1 parent 93fa7b3 commit 9ea62ca
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 50 deletions.
64 changes: 64 additions & 0 deletions iOS-NOTTODO/Widget-NOTTODO/Network/Service/WidgetService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// WidgetService.swift
// iOS-NOTTODO
//
// Created by 강윤서 on 5/10/24.
//

import Foundation

typealias QuoteData = GeneralResponse<QuoteResponseDTO>

struct WidgetService {

static let shared = WidgetService()
private init() {}

private let session = URLSession.shared

func fetchWiseSaying() async throws -> QuoteResponseDTO {
do {
return try await getWiseSaying(from: generateURL())
} catch {
switch error {
case NetworkError.networkError:
print("네트워크 에러가 발생")
case NetworkError.invalidResponse:
print("유효하지 않은 응답")
case NetworkError.dataParsingError:
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 generateURL() -> URL {
let baseURL = Bundle.main.baseURL
let url = baseURL + URLConstant.quote
return URL(string: url)!
}
}
46 changes: 46 additions & 0 deletions iOS-NOTTODO/Widget-NOTTODO/Provider/MissionProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// 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()

func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(todayMission: [], quote: "")
}

func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
do {
let entry = try await getTimelineEntry()
return entry
} catch {
return SimpleEntry(todayMission: [], quote: "")
}
}

func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
do {
let entry = try await getTimelineEntry()
return Timeline(entries: [entry], policy: .never)
} catch {
return Timeline(entries: [], policy: .never)
}

}

private func getTimelineEntry() async throws -> SimpleEntry {
guard let decodedData = try? JSONDecoder().decode([DailyMissionResponseDTO].self, from: sharedData) else {
return SimpleEntry(todayMission: [], quote: "")
}

let quoteResponse = try await WidgetService.shared.fetchWiseSaying()
let quote = quoteResponse.description + " - " + quoteResponse.author
return SimpleEntry(todayMission: decodedData, quote: quote)
}
}
14 changes: 14 additions & 0 deletions iOS-NOTTODO/Widget-NOTTODO/Provider/TimeEntity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// TimeEntity.swift
// iOS-NOTTODO
//
// Created by 강윤서 on 5/11/24.
//

import WidgetKit

struct SimpleEntry: TimelineEntry {
var date: Date = .now
var todayMission: [DailyMissionResponseDTO]
let quote: String
}
11 changes: 6 additions & 5 deletions iOS-NOTTODO/Widget-NOTTODO/View/MediumFamily.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct MediumFamily: View {
@AppStorage("dayOfWeek", store: UserDefaults.shared) var dayOfWeek: String = ""

var body: some View {
let progressPercent = Double(entry.lastThreeTask.filter { $0.completionStatus == .CHECKED }.count) / Double(entry.lastThreeTask.count)
let progressPercent = Double(entry.todayMission.filter { $0.completionStatus == .CHECKED }.count) / Double(entry.todayMission.count)
HStack {
VStack {
ZStack {
Expand All @@ -28,19 +28,20 @@ struct MediumFamily: View {
.padding(.leading, 17)

VStack {
Text("성공한상위십퍼센트는하하글자수가과연어디까지일까요하하하먼저하지말아야할어쩌구저쩌구")
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.lastThreeTask.isEmpty {
if entry.todayMission.isEmpty {
Button(action: {
print("앱으로 이동")
}, label: {
Expand All @@ -50,7 +51,7 @@ struct MediumFamily: View {
.buttonStyle(.plain)
.position(x: 10, y: 9)
} else {
ForEach(entry.lastThreeTask) { task in
ForEach(entry.todayMission) { task in
HStack {
Button(intent: ToggleButtonIntent(id: task.id)) {
Image(task.completionStatus == .CHECKED ? .btnMediumFill : .btnMedium)
Expand Down Expand Up @@ -82,5 +83,5 @@ struct MediumFamily: View {
#Preview(as: .systemMedium) {
Widget_NOTTODO()
} timeline: {
SimpleEntry(lastThreeTask: [])
SimpleEntry(todayMission: [], quote: "")
}
9 changes: 5 additions & 4 deletions iOS-NOTTODO/Widget-NOTTODO/View/SmallFamily.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct SmallFamily: View {
@AppStorage("dayOfWeek", store: UserDefaults.shared) var dayOfWeek: String = ""

var body: some View {
let progressPercent = Double(entry.lastThreeTask.filter { $0.completionStatus == .CHECKED }.count) / Double(entry.lastThreeTask.count)
let progressPercent = Double(entry.todayMission.filter { $0.completionStatus == .CHECKED }.count) / Double(entry.todayMission.count)

VStack {
HStack {
Expand All @@ -28,19 +28,20 @@ struct SmallFamily: View {
CircularProgressBarView(percent: progressPercent, size: 27, lineWidth: 3)
}

Text("성공하지않는거엊이ㅏ러미아러어쩌구요명어니아러나어ㅏ아아아")
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.lastThreeTask.isEmpty {
if entry.todayMission.isEmpty {
Button(action: {
print("앱으로 이동")
}, label: {
Expand All @@ -50,7 +51,7 @@ struct SmallFamily: View {
.buttonStyle(.plain)
.position(x: 17, y: 12)
} else {
ForEach(entry.lastThreeTask) { task in
ForEach(entry.todayMission) { task in
HStack {
Button(intent: ToggleButtonIntent(id: task.id)) {
Image(task.completionStatus == .CHECKED ? .btnSmallBoxFill : .btnSmallBox)
Expand Down
48 changes: 7 additions & 41 deletions iOS-NOTTODO/Widget-NOTTODO/Widget_NOTTODO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,58 +8,24 @@
import WidgetKit
import SwiftUI

struct Provider: AppIntentTimelineProvider {
@AppStorage("dailyMission", store: UserDefaults.shared) var sharedData: Data = Data()
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(lastThreeTask: [])
}

func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
if let decodedData = try? JSONDecoder().decode([DailyMissionResponseDTO].self, from: sharedData) {
return SimpleEntry(lastThreeTask: decodedData)
}
return SimpleEntry(lastThreeTask: [])
}

func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
if let decodedData = try? JSONDecoder().decode([DailyMissionResponseDTO].self, from: sharedData) {
let entries: [SimpleEntry] = [SimpleEntry(lastThreeTask: decodedData)]

return Timeline(entries: entries, policy: .never)
}

return Timeline(entries: [], policy: .never)
}
}

struct SimpleEntry: TimelineEntry {
let date: Date = .now
var lastThreeTask: [DailyMissionResponseDTO]
}

struct Widget_NOTTODOEntryView: View {
@Environment(\.widgetFamily) var family: WidgetFamily
var entry: Provider.Entry

@ViewBuilder
var body: some View {
@AppStorage("dailyMission", store: UserDefaults.shared) var sharedData: Data = Data()

if let decodedData = try? JSONDecoder().decode([DailyMissionResponseDTO].self, from: sharedData) {

switch self.family {
case .systemSmall:
SmallFamily(entry: SimpleEntry(lastThreeTask: decodedData))
default:
MediumFamily(entry: SimpleEntry(lastThreeTask: decodedData))
}
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)
Expand All @@ -75,5 +41,5 @@ struct Widget_NOTTODO: Widget {
#Preview(as: .systemMedium) {
Widget_NOTTODO()
} timeline: {
SimpleEntry(lastThreeTask: [])
SimpleEntry(todayMission: [], quote: "")
}

0 comments on commit 9ea62ca

Please sign in to comment.