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
20 changes: 20 additions & 0 deletions Atcha-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
6DC3BF682E0721F300831470 /* LoginDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC3BF672E0721F300831470 /* LoginDTO.swift */; };
6DC617A72F60EB1A002DD641 /* LocationSmoother.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC617A62F60EB1A002DD641 /* LocationSmoother.swift */; };
6DC617A92F610238002DD641 /* HomeArrivalManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC617A82F610238002DD641 /* HomeArrivalManager.swift */; };
6DC617AD2F62EB59002DD641 /* HomeRegistrationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC617AC2F62EB59002DD641 /* HomeRegistrationCoordinator.swift */; };
6DD632B12E4F8A9F00C6A66E /* CheckServiceRegionRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD632B02E4F8A9F00C6A66E /* CheckServiceRegionRequest.swift */; };
6DD632B62E52E23A00C6A66E /* ProximityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD632B52E52E23A00C6A66E /* ProximityManager.swift */; };
6DD632B92E52E8E300C6A66E /* ProximityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD632B82E52E8E300C6A66E /* ProximityViewController.swift */; };
Expand Down Expand Up @@ -476,6 +477,7 @@
6DC3BF672E0721F300831470 /* LoginDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginDTO.swift; sourceTree = "<group>"; };
6DC617A62F60EB1A002DD641 /* LocationSmoother.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSmoother.swift; sourceTree = "<group>"; };
6DC617A82F610238002DD641 /* HomeArrivalManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeArrivalManager.swift; sourceTree = "<group>"; };
6DC617AC2F62EB59002DD641 /* HomeRegistrationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeRegistrationCoordinator.swift; sourceTree = "<group>"; };
6DD632B02E4F8A9F00C6A66E /* CheckServiceRegionRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckServiceRegionRequest.swift; sourceTree = "<group>"; };
6DD632B52E52E23A00C6A66E /* ProximityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProximityManager.swift; sourceTree = "<group>"; };
6DD632B82E52E8E300C6A66E /* ProximityViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProximityViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -691,6 +693,7 @@
6D1EE2D62E08E4AB00F7BBF1 /* HomeRegister */ = {
isa = PBXGroup;
children = (
6DC617AB2F62EB4B002DD641 /* Coordinator */,
6D1EE2D92E08E4E000F7BBF1 /* HomeRegisterViewController.swift */,
6D1EE2DB2E08E4EA00F7BBF1 /* HomeRegisterViewModel.swift */,
);
Expand Down Expand Up @@ -1113,6 +1116,21 @@
path = Login;
sourceTree = "<group>";
};
6DC617AA2F62E931002DD641 /* ChangeHome */ = {
isa = PBXGroup;
children = (
);
path = ChangeHome;
sourceTree = "<group>";
};
6DC617AB2F62EB4B002DD641 /* Coordinator */ = {
isa = PBXGroup;
children = (
6DC617AC2F62EB59002DD641 /* HomeRegistrationCoordinator.swift */,
);
path = Coordinator;
sourceTree = "<group>";
};
6DD632AE2E4F8A6600C6A66E /* SearchLocation */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1311,6 +1329,7 @@
B65C12D82E042A320016D2F0 /* DIContainer */ = {
isa = PBXGroup;
children = (
6DC617AA2F62E931002DD641 /* ChangeHome */,
6D61ABE62F57174500111C9B /* Intro */,
B61C44962E40340C00285A4B /* LockScreen */,
6D2B8CB62E39C87F00608104 /* BusInfo */,
Expand Down Expand Up @@ -2150,6 +2169,7 @@
6DB7636D2E45C69400D06A49 /* AlarmRepository.swift in Sources */,
6DB7636F2E45C6D100D06A49 /* AlarmRepositoryImpl.swift in Sources */,
B65C12E22E042D400016D2F0 /* FetchUserUseCase.swift in Sources */,
6DC617AD2F62EB59002DD641 /* HomeRegistrationCoordinator.swift in Sources */,
B6EDD73C2E0D87F2006170DF /* FileStorageImpl.swift in Sources */,
B6793D4B2E3493D6001BE9F5 /* AtcahaInsetLabel.swift in Sources */,
6D2B8CB52E39AC7200608104 /* BusPositionInfoResponse.swift in Sources */,
Expand Down
11 changes: 11 additions & 0 deletions Atcha-iOS/App/DIContainer/Main/MainDIContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ final class MainDIContainer {
LoginDIContainer(apiService: apiService)
}()

private lazy var homeRegisterDI: HomeRegisterDIContainer = {
HomeRegisterDIContainer(apiService: apiService, locationStateHolder: locationStateHolder)
}()

init(apiService: APIService, locationStateHolder: LocationStateHolder) {
self.apiService = apiService
self.locationStateHolder = locationStateHolder
Expand Down Expand Up @@ -128,3 +132,10 @@ extension MainDIContainer{
}
}


// MARK: - HomeRegister
extension MainDIContainer{
func makeHomeRegisterDIContainer() -> HomeRegisterDIContainer {
return homeRegisterDI
}
}
13 changes: 9 additions & 4 deletions Atcha-iOS/Core/Manager/LocationSmoother.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,23 @@ import MapKit
final class LocationSmoother {
private var buffer: [CLLocationCoordinate2D] = []
private let bufferLimit: Int

init(limit: Int = 5) {
self.bufferLimit = limit
}


func reset(_ coordinate: CLLocationCoordinate2D) {
buffer.removeAll()
buffer.append(coordinate)
}

func smooth(_ next: CLLocationCoordinate2D) -> CLLocationCoordinate2D {
buffer.append(next)
if buffer.count > bufferLimit { buffer.removeFirst() }

let avgLat = buffer.map { $0.latitude }.reduce(0, +) / Double(buffer.count)
let avgLon = buffer.map { $0.longitude }.reduce(0, +) / Double(buffer.count)

return CLLocationCoordinate2D(latitude: avgLat, longitude: avgLon)
}
}
Expand Down
2 changes: 2 additions & 0 deletions Atcha-iOS/DesignSource/AtchaColor/AtchaColor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ enum AtchaColor{
static let remainTime = UIColor(named: "remainTime")!
static let paddingLabel = UIColor(named: "paddingLabel")!
}

static let neutral = UIColor(named: "neutral")
// MARK: - 사용 예시
//
// titleLabel.textColor = AtchaColor.gray900
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x42",
"green" : "0x3C",
"red" : "0x39"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ enum MainRoute {
case proximity // 가까운 거리 알림 모달
case dismissLockScreen
case loginSheet
case changeHome
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ final class DetailRouteBusCell: UICollectionViewCell {
private var isArrivedEffectOn = false
private var isAlarmFired: Bool = false

private var hasMetZero: Bool = false
private var isBoarded: Bool = false
private var hasDepartedStartStation: Bool = false

override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
Expand Down Expand Up @@ -114,6 +118,10 @@ final class DetailRouteBusCell: UICollectionViewCell {

isAlarmFired = false
busTimerStackView.isHidden = true

hasMetZero = false
isBoarded = false
hasDepartedStartStation = false
}

override func preferredLayoutAttributesFitting(
Expand Down Expand Up @@ -354,12 +362,24 @@ final class DetailRouteBusCell: UICollectionViewCell {
}
}

func isNowUserLocationArrived() {
if isArrivedEffectOn { return }
func isNowUserLocationArrived(hasDeparted: Bool = false) {
// 정류장에 도착해서 0초(도착)를 본 적이 있을 때만 '출발'을 인정합니다.
if hasDeparted && hasMetZero {
self.hasDepartedStartStation = true
}

if isArrivedEffectOn {
// 출발 상태가 들어왔다면 라벨 갱신 (탑승 완료 띄우기)
if self.hasDepartedStartStation { updateBusTimerLabels() }
return
}

isArrivedEffectOn = true
animationView.isHidden = false
animationView.startAnimationIfNeeded(forceRestart: true)
backgroundColor = UIColor.opacity100

updateBusTimerLabels()
}

func stopArrivedEffectIfNeeded() {
Expand Down Expand Up @@ -479,28 +499,30 @@ extension DetailRouteBusCell {
}

// 1초마다 감소
private func decrementRemainingTime() {
guard !currentBusInfo.isEmpty else {
stopCountdownTimer()
return
}

for i in 0..<currentBusInfo.count {
guard let time = currentBusInfo[i].remainingTime else { continue }
currentBusInfo[i].remainingTime = time - 1
}

currentBusInfo = currentBusInfo.filter { ($0.remainingTime ?? -1) > 0 }

if currentBusInfo.isEmpty {
stopCountdownTimer()
busTimerFirstLabel.attributedText = AtchaFont.B6_R_14("도착 또는 출발", color: .widearea)
// busTimerSecondLabel.text = ""
return
private func decrementRemainingTime() {
guard !currentBusInfo.isEmpty else {
stopCountdownTimer()
return
}

for i in 0..<currentBusInfo.count {
guard let time = currentBusInfo[i].remainingTime else { continue }
currentBusInfo[i].remainingTime = time - 1
}

// 문제 발생 부분!
// 0보다 큰 것만 남기면 타이머가 0초에서 리스트에서 사라져 버려서
// -60초(1분) 대기 조건이나 탑승 완료 판정을 탈 수가 없습니다.
currentBusInfo = currentBusInfo.filter { ($0.remainingTime ?? -1) > 0 }

if currentBusInfo.isEmpty {
stopCountdownTimer()
busTimerFirstLabel.attributedText = AtchaFont.B6_R_14("도착 또는 출발", color: .widearea)
return
}

updateBusTimerLabels()
}

updateBusTimerLabels()
}

private func updateBusTimerLabels() {

Expand All @@ -512,15 +534,42 @@ extension DetailRouteBusCell {
busTimerStackView.isHidden = false

func labelText(for info: RealTimeBusArrival) -> NSAttributedString {
if self.isBoarded {
return AtchaFont.B6_R_14("탑승 완료", color: .gray300)
}

if info.busStatus == .end {
return AtchaFont.B6_R_14("운행 종료", color: .gray)
}

guard let remaining = info.remainingTime else {
return AtchaFont.B6_R_14("", color: .gray300)
// 예외처리: API 갱신으로 정보가 날아갔는데 0초를 본 적이 있다면 탑승으로 간주
if self.hasMetZero {
self.isBoarded = true
return AtchaFont.B6_R_14("탑승 완료", color: .gray300)
} else {
return AtchaFont.B6_R_14("", color: .gray300)
}
}

if remaining <= 0 {
self.hasMetZero = true
}

if self.hasMetZero {
// (1) 도착 후 60초가 지났거나
// (2) 0초를 봤는데 API가 갱신되었거나
// (3) 정류장에서 150m 멀어짐을 감지했을 때
if remaining <= -60 || (remaining > 0 && self.isArrivedEffectOn) || self.hasDepartedStartStation {
self.isBoarded = true
self.stopCountdownTimer() // 버스 타이머 멈춤
return AtchaFont.B6_R_14("탑승 완료", color: .gray300)
}
}

if remaining <= 120 {
if remaining <= 0 {
return AtchaFont.B6_R_14("도착 또는 출발", color: .widearea)
} else if remaining <= 120 {
return AtchaFont.B6_R_14("곧 도착", color: .widearea)
} else {
return AtchaFont.B6_R_14(formatSecondsToHMS(remaining), color: .widearea)
Expand Down
Loading
Loading