Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
A3BC2F432966A93100198261 /* CourseDetailVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F422966A93100198261 /* CourseDetailVC.swift */; };
A3F67AE2296D33AC001598A2 /* MyPageDto.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3F67AE1296D33AC001598A2 /* MyPageDto.swift */; };
A3F67AE4296D33E0001598A2 /* MyPageRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3F67AE3296D33E0001598A2 /* MyPageRouter.swift */; };
A3F67AEA296E4936001598A2 /* ActivityRecordInfoDto.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3F67AE9296E4936001598A2 /* ActivityRecordInfoDto.swift */; };
CE0C23742966D62A00B45063 /* PagedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0C23732966D62A00B45063 /* PagedView.swift */; };
CE0C23772966D64D00B45063 /* PageCVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0C23762966D64D00B45063 /* PageCVC.swift */; };
CE0C23792966D6AF00B45063 /* ViewPager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0C23782966D6AF00B45063 /* ViewPager.swift */; };
Expand Down Expand Up @@ -156,6 +157,7 @@
A3BC2F422966A93100198261 /* CourseDetailVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDetailVC.swift; sourceTree = "<group>"; };
A3F67AE1296D33AC001598A2 /* MyPageDto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageDto.swift; sourceTree = "<group>"; };
A3F67AE3296D33E0001598A2 /* MyPageRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageRouter.swift; sourceTree = "<group>"; };
A3F67AE9296E4936001598A2 /* ActivityRecordInfoDto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityRecordInfoDto.swift; sourceTree = "<group>"; };
CE0C23732966D62A00B45063 /* PagedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagedView.swift; sourceTree = "<group>"; };
CE0C23762966D64D00B45063 /* PageCVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageCVC.swift; sourceTree = "<group>"; };
CE0C23782966D6AF00B45063 /* ViewPager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewPager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -411,6 +413,7 @@
children = (
CE10063D29680C8100FD31FB /* .gitkeep */,
A3F67AE1296D33AC001598A2 /* MyPageDto.swift */,
A3F67AE9296E4936001598A2 /* ActivityRecordInfoDto.swift */,
);
path = MyPageDto;
sourceTree = "<group>";
Expand Down Expand Up @@ -1325,6 +1328,7 @@
CE6655C8295D849F00C64E12 /* StringLiterals.swift in Sources */,
DAD5A3E4296D526D00C8166B /* CourseDiscoveryRouter.swift in Sources */,
CEEC6B3E2961C53700D00E1E /* CourseDiscoveryVC.swift in Sources */,
A3F67AEA296E4936001598A2 /* ActivityRecordInfoDto.swift in Sources */,
CE6655E0295D87D200C64E12 /* UIDevice+.swift in Sources */,
DA97A02F296DC3300086760E /* CourseSearchingRouter.swift in Sources */,
CE40BB242968068E0030ABCA /* Config.swift in Sources */,
Expand Down
11 changes: 11 additions & 0 deletions Runnect-iOS/Runnect-iOS/Global/Utils/RNUtils/RNTimeFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,15 @@ class RNTimeFormatter {

return formatter.string(from: date)
}

static func changeDateSplit(date: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let convertDate = dateFormatter.date(from: date)

let resultDateFormatter = DateFormatter()
resultDateFormatter.dateFormat = "yyyy.MM.dd"

return resultDateFormatter.string(from: convertDate!)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// ActivityRecordInfoDto.swift
// Runnect-iOS
//
// Created by 몽이 누나 on 2023/01/11.
//

import Foundation

// MARK: - ActivityRecordInfoDto

struct ActivityRecordInfoDto: Codable {
let records: [ActivityRecord]
}

// MARK: - Record

struct ActivityRecord: Codable {
let id, courseId: Int
let publicCourseId: Int?
let machineId, title: String
let image: String
let createdAt: String
let distance: Double
let time, pace: String
let departure: ActivityRecordDeparture
}

// MARK: - Departure

struct ActivityRecordDeparture: Codable {
let region, city: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Moya
enum MyPageRouter {
case getMyPageInfo
case getUploadedCourseInfo
case getActivityRecordInfo
}

extension MyPageRouter: TargetType {
Expand All @@ -29,6 +30,8 @@ extension MyPageRouter: TargetType {
return "/user"
case .getUploadedCourseInfo:
return "/public-course/user"
case .getActivityRecordInfo:
return "/record/user"
}
}

Expand All @@ -38,6 +41,8 @@ extension MyPageRouter: TargetType {
return .get
case .getUploadedCourseInfo:
return .get
case .getActivityRecordInfo:
return .get
}
}

Expand All @@ -47,6 +52,8 @@ extension MyPageRouter: TargetType {
return .requestPlain
case .getUploadedCourseInfo:
return .requestPlain
case .getActivityRecordInfo:
return .requestPlain
}
}

Expand All @@ -58,6 +65,9 @@ extension MyPageRouter: TargetType {
case .getUploadedCourseInfo:
return ["Content-Type": "application/json",
"machineId": "1"]
case .getActivityRecordInfo:
return ["Content-Type": "application/json",
"machineId": "1"]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
//

import UIKit

import SnapKit
import Then
import Kingfisher

final class ActivityRecordInfoTVC: UITableViewCell {

Expand All @@ -23,7 +25,7 @@ final class ActivityRecordInfoTVC: UITableViewCell {
private let firstVerticalDivideLine = UIView()
private let secondVerticalDivideLine = UIView()

private let activityRecordMapImage = UIView().then {
private let activityRecordMapImage = UIImageView().then {
$0.layer.cornerRadius = 10
}

Expand Down Expand Up @@ -71,7 +73,7 @@ final class ActivityRecordInfoTVC: UITableViewCell {

private lazy var activityRecordSubInfoStackView = UIStackView(arrangedSubviews: [activityRecordTotalDistanceStackView, firstVerticalDivideLine, activityRecordRunningTimeStackView, secondVerticalDivideLine, activityRecordAveragePaceStackView]).then {
$0.axis = .horizontal
$0.distribution = .fillProportionally
$0.distribution = .fill
}

// MARK: - Life Cycles
Expand All @@ -87,6 +89,57 @@ final class ActivityRecordInfoTVC: UITableViewCell {
}
}

// MARK: - Methods

extension ActivityRecordInfoTVC {
func setData(model: ActivityRecord) {
guard let imageURL = URL(string: model.image) else { return }

// 날짜 바꾸기
let activityRecordDate = model.createdAt.prefix(10)
let resultDate = RNTimeFormatter.changeDateSplit(date: String(activityRecordDate))

// 이동 시간 바꾸기
let activityRecordRunningTime = model.time.suffix(7)

// 평균 페이스 바꾸기
let activityRecordAveragePace = model.pace
let array = spiltActivityRecordAveragePace(model: model)

activityRecordTitleLabel.text = model.title
setUpActivityRecordPlaceLabel(model: model, label: activityRecordPlaceLabel)
activityRecordDateLabel.text = resultDate
setUpactivityRecordTotalDistanceValueLabel(model: model, label: activityRecordTotalDistanceValueLabel)
activityRecordRunningTimeValueLabel.text = String(activityRecordRunningTime)
setUpActivityRecordAveragePaceValueLabel(array: array, label: activityRecordAveragePaceValueLabel)
self.activityRecordMapImage.kf.setImage(with: imageURL)
}

private func setUpActivityRecordPlaceLabel(model: ActivityRecord, label: UILabel) {
let attributedString = NSMutableAttributedString(string: String(model.departure.region) + " ", attributes: [.font: UIFont.b8, .foregroundColor: UIColor.g2])
attributedString.append(NSAttributedString(string: String(model.departure.city), attributes: [.font: UIFont.b8, .foregroundColor: UIColor.g2]))
label.attributedText = attributedString
}

private func setUpactivityRecordTotalDistanceValueLabel(model: ActivityRecord, label: UILabel) {
let attributedString = NSMutableAttributedString(string: String(model.distance) + " ", attributes: [.font: UIFont.h5, .foregroundColor: UIColor.g1])
attributedString.append(NSAttributedString(string: "km", attributes: [.font: UIFont.b4, .foregroundColor: UIColor.g1]))
label.attributedText = attributedString
}

private func setUpActivityRecordAveragePaceValueLabel(array: [String], label: UILabel) {
let attributedString = NSMutableAttributedString(string: String(array[1]) + "’", attributes: [.font: UIFont.h5, .foregroundColor: UIColor.g1])
attributedString.append(NSAttributedString(string: String(array[2]) + "”", attributes: [.font: UIFont.h5, .foregroundColor: UIColor.g1]))
label.attributedText = attributedString
}

private func spiltActivityRecordAveragePace(model: ActivityRecord) -> [String] {
let activityRecordAveragePace = model.pace
let array = activityRecordAveragePace.split(separator: ":").map { String($0) }
return array
}
}

extension ActivityRecordInfoTVC {

// MARK: - Method
Expand Down Expand Up @@ -167,9 +220,28 @@ extension ActivityRecordInfoTVC {
make.width.equalTo(1)
}

setActivityRecordSubInfoStackView()
}

private func setActivityRecordSubInfoStackView() {
let screenWidth = UIScreen.main.bounds.width
let containerViewWidth = screenWidth - 32
let stackViewWidth = Int(containerViewWidth - 2) / 3

activityRecordTotalDistanceStackView.snp.makeConstraints { make in
make.width.equalTo(stackViewWidth)
}

activityRecordRunningTimeStackView.snp.makeConstraints { make in
make.width.equalTo(stackViewWidth)
}

activityRecordAveragePaceStackView.snp.makeConstraints { make in
make.width.equalTo(stackViewWidth)
}

activityRecordSubInfoStackView.snp.makeConstraints { make in
make.top.equalTo(horizontalDivideLine.snp.bottom).offset(15)
make.width.equalToSuperview()
make.centerX.equalToSuperview()
}
}
Expand All @@ -178,15 +250,4 @@ extension ActivityRecordInfoTVC {
super.layoutSubviews()
contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: 16, right: 0))
}

// MARK: - General Helpers

func dataBind(model: ActivityRecordInfoModel) {
activityRecordTitleLabel.text = model.title
activityRecordPlaceLabel.text = model.place
activityRecordDateLabel.text = model.date
activityRecordTotalDistanceValueLabel.text = model.distance
activityRecordRunningTimeValueLabel.text = model.runningTime
activityRecordAveragePaceValueLabel.text = model.averagePace
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
//

import UIKit

import SnapKit
import Then
import Moya

final class ActivityRecordInfoVC: UIViewController {

// MARK: - Properties

var activityRecordList: [ActivityRecordInfoModel] = [
ActivityRecordInfoModel(title: "석촌 호수 한 바퀴", place: "서울시 강동구", date: "2022.12.28", distance: "4.01 km", runningTime: "0:27:36", averagePace: "6'45\""),
ActivityRecordInfoModel(title: "석촌 호수 한 바퀴", place: "서울시 강동구", date: "2022.12.29", distance: "4.01 km", runningTime: "0:27:36", averagePace: "6'45\""),
ActivityRecordInfoModel(title: "석촌 호수 한 바퀴", place: "서울시 강동구", date: "2022.12.30", distance: "4.01 km", runningTime: "0:27:36", averagePace: "6'45\""),
ActivityRecordInfoModel(title: "석촌 호수 한 바퀴", place: "서울시 강동구", date: "2022.12.31", distance: "4.01 km", runningTime: "0:27:36", averagePace: "6'45\""),
ActivityRecordInfoModel(title: "석촌 호수 한 바퀴", place: "서울시 강동구", date: "2022.12.28", distance: "4.01 km", runningTime: "0:27:36", averagePace: "6'45\""),
ActivityRecordInfoModel(title: "석촌 호수 한 바퀴", place: "서울시 강동구", date: "2022.12.28", distance: "4.01 km", runningTime: "0:27:36", averagePace: "6'45\"")
]
private var activityRecordProvider = MoyaProvider<MyPageRouter>(
plugins: [NetworkLoggerPlugin(verbose: true)]
)

private var activityRecordList = [ActivityRecord]()

// MARK: - UI Components

Expand All @@ -29,8 +28,6 @@ final class ActivityRecordInfoVC: UIViewController {
private lazy var activityRecordTableView = UITableView().then {
$0.showsVerticalScrollIndicator = false
$0.separatorStyle = .none
$0.delegate = self
$0.dataSource = self
}

// MARK: - View Life Cycle
Expand All @@ -40,7 +37,27 @@ final class ActivityRecordInfoVC: UIViewController {
setNavigationBar()
setUI()
setLayout()
setDelegate()
register()
getActivityRecordInfo()
}
}

// MARK: - Methods

extension ActivityRecordInfoVC {
private func setData(activityRecordList: [ActivityRecord]) {
self.activityRecordList = activityRecordList
activityRecordTableView.reloadData()
}

private func setDelegate() {
self.activityRecordTableView.delegate = self
self.activityRecordTableView.dataSource = self
}

private func register() {
self.activityRecordTableView.register(ActivityRecordInfoTVC.self, forCellReuseIdentifier: ActivityRecordInfoTVC.className)
}
}

Expand Down Expand Up @@ -71,12 +88,6 @@ extension ActivityRecordInfoVC {
make.bottom.equalToSuperview()
}
}

// MARK: - General Helpers

private func register() {
activityRecordTableView.register(ActivityRecordInfoTVC.self, forCellReuseIdentifier: ActivityRecordInfoTVC.className)
}
}

// MARK: - UITableViewDelegate
Expand All @@ -97,7 +108,39 @@ extension ActivityRecordInfoVC: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let activityRecordCell = tableView.dequeueReusableCell(withIdentifier: ActivityRecordInfoTVC.className, for: indexPath) as? ActivityRecordInfoTVC else { return UITableViewCell()}
activityRecordCell.selectionStyle = .none
activityRecordCell.dataBind(model: activityRecordList[indexPath.item])
activityRecordCell.setData(model: activityRecordList[indexPath.item])
return activityRecordCell
}
}

// MARK: - Network

extension ActivityRecordInfoVC {
func getActivityRecordInfo() {
LoadingIndicator.showLoading()
activityRecordProvider.request(.getActivityRecordInfo) { [weak self] response in
LoadingIndicator.hideLoading()
guard let self = self else { return }
switch response {
case .success(let result):
let status = result.statusCode
if 200..<300 ~= status {
do {
let responseDto = try result.map(BaseResponse<ActivityRecordInfoDto>.self)
guard let data = responseDto.data else { return }
self.setData(activityRecordList: data.records)
} catch {
print(error.localizedDescription)
}
}
if status >= 400 {
print("400 error")
self.showNetworkFailureToast()
}
case .failure(let error):
print(error.localizedDescription)
self.showNetworkFailureToast()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,4 @@ extension UploadedCourseInfoCVC {
make.leading.equalToSuperview()
}
}

// MARK: - General Helpers

func dataBind(model: UploadedCourseInfoModel) {
uploadedCourseTitleLabel.text = model.title
uploadedCoursePlaceLabel.text = model.place
}

}