Skip to content

Commit

Permalink
feat #52: 마이페이지 API 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
enebin committed Aug 18, 2023
1 parent 8f11bf7 commit d8daecf
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 160 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ disabled_rules:
- type_body_length
- no_fallthrough_only
- multiple_closures_with_trailing_closure
- identifier_name

analyzer_rules:
- explicit_self
Expand Down
11 changes: 6 additions & 5 deletions Projects/Domain/Sources/Client/TestClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ extension DependencyValues {
extension TestClient: DependencyKey {
public static var liveValue = TestClient(
fetchTest: {
let api = TestAPI.hello
let response = try await TestAPIManager.shared.request(api)
let decoded = String(data: response.data, encoding: .utf8)!

return TestDTO(hello: decoded).toModel()
// let api = TestAPI.hello
// let response = try await TestAPIManager.shared.request(api)
// let decoded = String(data: response.data, encoding: .utf8)!
//
// return TestDTO(hello: decoded).toModel()
return .init(hello: "")
}
)
}
89 changes: 88 additions & 1 deletion Projects/Domain/Sources/Model/CirclePack/CircleData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Copyright © 2023 team.humanwave. All rights reserved.
//

import Core
import SwiftUI
import Foundation

Expand All @@ -20,7 +21,13 @@ public struct CircleData {
public let metadata: CircleMetadata

static public func emptyCircle(radius: CGFloat) -> CircleData {
self.init(isEmptyCircle: true, color: .clear, xPoint: 0, yPoint: 0, radius: radius, metadata: CircleMetadata.emptyData)
self.init(
isEmptyCircle: true,
color: .clear,
xPoint: 0,
yPoint: 0,
radius: radius,
metadata: CircleMetadata.emptyData)
}

public init(
Expand Down Expand Up @@ -51,6 +58,86 @@ public struct CircleData {
}
}

// 네트워크 데이터
public extension CircleData {
// MARK: - AppResult
struct NetworkResult: Codable {
let data: DataField

struct DataField: Codable {
let memberID: Int
let results: [Result]

enum CodingKeys: String, CodingKey {
case memberID = "memberId"
case results
}
}
}
}

extension CircleData.NetworkResult {
struct Result: Codable {
let questionStatistic: QuestionStatistic
let coordinate: Coordinate
}

struct Coordinate: Codable {
let x, y, r: Double
}

struct QuestionStatistic: Codable {
let questionID: Int
let title, keyword: String
let category: Category
let avgScore: Int

enum CodingKeys: String, CodingKey {
case questionID = "questionId"
case title, keyword, category, avgScore
}
}

struct Category: Codable {
let iconURL: String
let name, color: String

enum CodingKeys: String, CodingKey {
case iconURL = "iconUrl"
case name, color
}
}
}

public extension CircleData.NetworkResult {
func toCircleData() -> [CircleData] {
return self.data.results.map { result -> CircleData in
let coordinate = result.coordinate
let questionStatistic = result.questionStatistic
let category = questionStatistic.category

let color = Color.hex(category.color)

let icon = Image(systemName: "person")

let metadata = CircleMetadata(
icon: icon,
keyword: questionStatistic.keyword,
averageScore: Float(questionStatistic.avgScore),
myScore: 0
)

return CircleData(
color: color,
xPoint: CGFloat(coordinate.x),
yPoint: CGFloat(coordinate.y),
radius: CGFloat(coordinate.r),
metadata: metadata
)
}
}
}

extension CircleData: Equatable {
public static func == (lhs: CircleData, rhs: CircleData) -> Bool {
lhs.id == rhs.id
Expand Down
133 changes: 80 additions & 53 deletions Projects/Features/Sources/MyPage/MyPageFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,79 +10,106 @@ import ComposableArchitecture
import Domain
import Foundation
import SwiftUI
import Network

struct MyPageFeature: Reducer {
struct State: Equatable {
var shownFirstTime = true
var circleDataList: [CircleData] = []
var circleShown = false
}
enum Action: Equatable {
case loadCircle
case saveCircle([CircleData])
case markViewAsShown
case circleTapped
case circleDismissed
}

public var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .loadCircle:
// TODO: API 갈아끼우기
state.circleDataList = [
CircleData(
color: .blue,
xPoint: 0.2068919881427701,
yPoint: 0.7022698911578201,
radius: 0.14644660940672627,
metadata: CircleMetadata(
icon: Image(systemName: "person.fill"),
keyword: "표현력",
averageScore: 4.2,
myScore: 4.2)),
CircleData(
color: .red,
xPoint: -0.20710678118654763,
yPoint: -0.4925857155047088,
radius: 0.20710678118654754,
metadata: CircleMetadata(
icon: Image(systemName: "person.fill"),
keyword: "표현력",
averageScore: 4.2,
myScore: 3.5)),
CircleData(
color: .gray,
xPoint: -0.2218254069479773,
yPoint: 0.6062444788590935,
radius: 0.29289321881345254,
metadata: CircleMetadata(
icon: Image(systemName: "person.fill"),
keyword: "표현력",
averageScore: 4.2,
myScore: 3.5)),
CircleData(
color: .cyan,
xPoint: -0.5857864376269051,
yPoint: 0.0,
radius: 0.4142135623730951,
metadata: CircleMetadata(
icon: Image(systemName: "person.fill"),
keyword: "표현력",
averageScore: 4.2,
myScore: 3.5)),
CircleData(
color: .mint,
xPoint: 0.4142135623730951,
yPoint: 0.0,
radius: 0.5857864376269051,
metadata: CircleMetadata(
icon: Image(systemName: "person.fill"),
keyword: "표현력",
averageScore: 4.2,
myScore: 3.5))
]
return .run { send in
let response = try await KeymeAPIManager.shared.request(
.myPage(.statistics(2)),
object: CircleData.NetworkResult.self)

await send(.saveCircle(response.toCircleData()))
}
// // TODO: API 갈아끼우기
// state.circleDataList = [
// CircleData(
// color: .blue,
// xPoint: 0.2068919881427701,
// yPoint: 0.7022698911578201,
// radius: 0.14644660940672627,
// metadata: CircleMetadata(
// icon: Image(systemName: "person.fill"),
// keyword: "표현력",
// averageScore: 4.2,
// myScore: 4.2)),
// CircleData(
// color: .red,
// xPoint: -0.20710678118654763,
// yPoint: -0.4925857155047088,
// radius: 0.20710678118654754,
// metadata: CircleMetadata(
// icon: Image(systemName: "person.fill"),
// keyword: "표현력",
// averageScore: 4.2,
// myScore: 3.5)),
// CircleData(
// color: .gray,
// xPoint: -0.2218254069479773,
// yPoint: 0.6062444788590935,
// radius: 0.29289321881345254,
// metadata: CircleMetadata(
// icon: Image(systemName: "person.fill"),
// keyword: "표현력",
// averageScore: 4.2,
// myScore: 3.5)),
// CircleData(
// color: .cyan,
// xPoint: -0.5857864376269051,
// yPoint: 0.0,
// radius: 0.4142135623730951,
// metadata: CircleMetadata(
// icon: Image(systemName: "person.fill"),
// keyword: "표현력",
// averageScore: 4.2,
// myScore: 3.5)),
// CircleData(
// color: .mint,
// xPoint: 0.4142135623730951,
// yPoint: 0.0,
// radius: 0.5857864376269051,
// metadata: CircleMetadata(
// icon: Image(systemName: "person.fill"),
// keyword: "표현력",
// averageScore: 4.2,
// myScore: 3.5))
// ]
case .saveCircle(let data):
state.circleDataList = data
return .none

case .markViewAsShown:
state.shownFirstTime = false
return .none

case .circleTapped:
state.circleShown = true
return .none

case .circleDismissed:
state.circleShown = false
return .none
}
}
}
}

extension MyPageFeature {

}
50 changes: 41 additions & 9 deletions Projects/Features/Sources/MyPage/MyPageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,48 @@ struct MyPageView: View {

public var body: some View {
WithViewStore(store, observe: { $0 }) { viewStore in
CirclePackView(
data: viewStore.state.circleDataList,
detailViewBuilder: { data in
ScoreListView(nickname: "ninkname", keyword: data.metadata.keyword, store: scoreListStore) // TODO: Change nickname
})
.graphBackgroundColor(.hex("232323"))
.activateCircleBlink(viewStore.state.shownFirstTime)
.onCircleDismissed { _ in
viewStore.send(.markViewAsShown)
ZStack(alignment: .topLeading) {
CirclePackView(
data: viewStore.state.circleDataList,
detailViewBuilder: { data in
ScoreListView(
nickname: "ninkname",
keyword: data.metadata.keyword,
store: scoreListStore) // TODO: Change nickname
})
.graphBackgroundColor(.hex("232323"))
.activateCircleBlink(viewStore.state.shownFirstTime)
.onCircleTapped { _ in
viewStore.send(.circleTapped)
}
.onCircleDismissed { _ in
withAnimation {
viewStore.send(.markViewAsShown)
viewStore.send(.circleDismissed)
}
}

if !viewStore.state.circleShown {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 4) {
Spacer()
Text.keyme("마이", font: .body3Semibold)
Image(systemName: "info.circle")
.resizable()
.frame(width: 16, height: 16)
.scaledToFit()
Spacer()
}
.padding(.top, 10)

Text.keyme("친구들이 생각하는\nnickname님의 성격은?", font: .heading1) // TODO: Change nickname
.padding(17)
.transition(.opacity)
}
.foregroundColor(.white)
}
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,14 @@ struct ScoreListView: View {

HStack {
Spacer()
Text.keyme("\(formatter.localizedString(for: scoreData.date, relativeTo: Date()))", font: .caption1)
.foregroundColor(.white.opacity(0.3))
Text.keyme(
"\(formatter.localizedString(for: scoreData.date, relativeTo: Date()))",
font: .caption1)
.foregroundColor(.white.opacity(0.3))
}
}
.padding(.horizontal, 12)
.frame(maxWidth: .infinity, minHeight: 85, maxHeight: 85)
.frame(maxWidth: .infinity, minHeight: 56, maxHeight: 56)
.background(keymeWhite.opacity(0.05))
.cornerRadius(16)
.onAppear {
Expand Down
2 changes: 1 addition & 1 deletion Projects/Features/Sources/Root/RootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public struct RootView: View {

public init() {
self.store = Store(initialState: RootFeature.State()) {
RootFeature()._printChanges()
RootFeature()
}

store.send(.checkLoginStatus)
Expand Down
5 changes: 3 additions & 2 deletions Projects/Keyme/Sources/KeymeApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import FirebaseMessaging

import Features

import DSKit
import Core
import Network

@main
struct KeymeApp: App {
Expand All @@ -29,6 +28,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
FirebaseApp.configure()
Messaging.messaging().delegate = self

KeymeAPIManager.shared.registerAuthorizationToken("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhY2Nlc3NUb2tlbiIsImlhdCI6MTY5MTg0MjM1NiwiZXhwIjoxNjk0NDM0MzU2LCJtZW1iZXJJZCI6Miwicm9sZSI6IlJPTEVfVVNFUiJ9.bLUl_ObvXr2pkLGNBZYWbJgLZLo3P0xB2pawckRGYZM")

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in
guard granted else { return }

Expand Down
Loading

0 comments on commit d8daecf

Please sign in to comment.