현재 유지보수 중인 버닝버디 앱의 추가 기능을 개발해야 한다.
[해야 할 일]
1인 기능 개발 (1월 20일 ~ ASAP)
- 이슈 생성
- 컨벤션 확인
- 린트 다운받기
- 린트에 맞게 코드 수정
- 추가 뷰 그리기 (차트)
- background, foreground일때 헬스 데이터 관리
- 피그마의 새로바뀐 로직에 맞게 1인 기능 잘 작동하게 바꾸기
[차트 기능 구현]
새로 업데이트된 차트에는 차트 1개짜리 있어서 쉽게 구현 가능할듯
-> 버닝버디의 앱은 iOS+17부터 있는 차트 기능을 사용하면 좋을듯
-> 앱의 생애주기 업데이트에 따라, 핼스 데이터를 실시간으로 받아오기 혹은 잠깐 멈춰있다가 앱이 켜지면 업데이트해줄지 중요 (생애주기가 업데이트가 가장 관권!), 앱 꺼졌을때, 켜졌을때 운동 데이터 관리해줘야 함!
foreground일떄는 계속 운동 데이터를 업데이트 해줘야 함
운동 데이터: 앱 스토리지같은 것을 사용하여 운동 데이터 저장하기
도넛 차트 구현
iOS 17부터 도넛 차트를 쉽게 구현할 수 있다.
https://developer.apple.com/videos/play/wwdc2023/10037/
Explore pie charts and interactivity in Swift Charts - WWDC23 - Videos - Apple Developer
Swift Charts has come full circle: Get ready to bake up pie and donut charts in your app with the latest improvements to the framework...
developer.apple.com
하지만, 우리 앱의 Minimum Deployments를 이 기능때문에 올릴 수는 없기 때문에, 해당 Charts에서 제공해주는 기능을 사용할 수 없다.

그래서 여러 방법을 찾아본 결과, SwiftUI로 구현된 앱에 UIKit을 추가해서 사용하기로 결정했다.
테스트 코드
UIKitTest.swift

//
// UIKitTest.swift
// ChartTest
//
// Created by Bokyung on 1/21/24.
//
import SwiftUI
struct TestView: UIViewRepresentable {
var value: CGFloat // value 매개변수 추가
func makeUIView(context: Context) -> UIView {
let customView = CustomView()
customView.value = self.value // value 값 전달
return customView
}
func updateUIView(_ uiView: UIView, context: Context) {
guard let customView = uiView as? CustomView else { return }
customView.value = value // value 값 업데이트
customView.setNeedsDisplay() // 변경사항을 반영하기 위해 화면을 다시 그립니다.
}
}
class CustomView: UIView {
var value: CGFloat = 0.0 // 데이터가 채워진 비율 (0.0부터 1.0까지)
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear // 배경색 지정
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = UIColor.clear // 배경색 지정
}
override func draw(_ rect: CGRect) {
// var value: CGFloat = 0.3 // 데이터가 채워진 비율 (0.0부터 1.0까지)
let center = CGPoint(x: rect.midX, y: rect.midY)
let radius: CGFloat = min(rect.width, rect.height) / 2 - 20
let grayColor = UIColor(named: "customGray") ?? UIColor.systemGray
let redColor = UIColor(named: "customRed") ?? UIColor.red
// 회색 선 경로
let grayPath = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
grayColor.setFill()
grayPath.fill()
// 가운데 뚫어주기
let innerPath = UIBezierPath(arcCenter: center, radius: radius - 28, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
grayColor.setFill()
innerPath.fill(with: .clear, alpha: 1.0) // 가운데를 뻥 뚫어줌
// 빨간 선 경로
let redPath = UIBezierPath(arcCenter: center, radius: radius - 14, startAngle: -.pi / 2, endAngle: -.pi / 2 + 2 * .pi * value, clockwise: true)
redColor.setStroke()
redPath.lineWidth = 28
redPath.lineCapStyle = .round // 끝 부분을 뭉툭하게 만듦
redPath.stroke()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
TestView(value: 0.3)
.frame(width: 249, height: 249)
}
}
ContentView.swift

value값을 통해 도넛차트의 붉은 부분이 표시
//
// ContentView.swift
// ChartTest
//
// Created by Bokyung on 1/21/24.
//
import SwiftUI
struct ContentView: View {
@State private var value: CGFloat = 0.0 // @State 변수 추가
var body: some View {
VStack {
TestView(value: value) // TestView로 value 전달
.frame(width: 249, height: 249)
Button("Change Value") {
if value < 1.0 {
value += 0.1 // 버튼을 눌러 value 값을 변경
} else {
value = 0
}
}
}
}
}
'회고 > Apple Developer Academy' 카테고리의 다른 글
[버닝버디] 1차 리팩토링 및 코드 정리 회고 (0) | 2024.02.17 |
---|