Skip to content

Commit

Permalink
fix/#78-watch help Q help me SOS
Browse files Browse the repository at this point in the history
  • Loading branch information
KimPilGyeom committed Nov 12, 2024
1 parent 1fcc78b commit 4975cc6
Show file tree
Hide file tree
Showing 23 changed files with 381 additions and 200 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "Icon .png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 37 additions & 27 deletions hearo/HearoadWatch Watch App/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,40 @@ import WatchKit

struct ContentView: View {
@ObservedObject var sessionManager = WatchSessionManager.shared

var body: some View {
ZStack {
// 배경색을 alert 상태에 따라 변경
sessionManager.isAlerting ? Color.red.edgesIgnoringSafeArea(.all) : Color.black.edgesIgnoringSafeArea(.all)

// 알림 상태에 따른 아이콘 표시
if sessionManager.isAlerting {
Image(sessionManager.alertImageName())
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
.padding()
} else {
// 알림이 아닐 때는 MainCircle 이미지를 표시
Image("MainCircle")
.resizable()
.frame(width: 200, height: 200)
.padding()
}
}
.onAppear {
// 초기화
sessionManager.resetAlert()
}
}
}

// 디바이스 화면 크기에 따라 동적으로 크기 조정
private var dynamicFrameSize: CGFloat {
let screenBounds = WKInterfaceDevice.current().screenBounds
let screenWidth = screenBounds.width
return screenWidth * 0.9 // 화면 너비의 90%를 기준으로 크기 설정
}

var body: some View {
// 배경색 변경: 알림 상태에 따라 다르게 설정
sessionManager.isAlerting ? Color.red.edgesIgnoringSafeArea(.all) : Color.black.edgesIgnoringSafeArea(.all)
ZStack {
VStack {
// 알림 상태에 따라 아이콘 표시
if sessionManager.isAlerting {
// 알림 메시지에 따른 아이콘 표시
Image(sessionManager.alertImageName())
.resizable()
.scaledToFit()
.frame(width: dynamicFrameSize, height: dynamicFrameSize)
.padding()
} else {
// 기본 상태 아이콘 표시
Image("Icon")
.resizable()
.scaledToFit()
.frame(width: dynamicFrameSize, height: dynamicFrameSize)
.padding()
}
}
}
.onAppear {
// 초기 상태로 초기화
sessionManager.resetAlert()
}
}
}
85 changes: 32 additions & 53 deletions hearo/HearoadWatch Watch App/WatchSessionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,91 +9,70 @@ import WatchKit
import WatchConnectivity

class WatchSessionManager: NSObject, ObservableObject, WCSessionDelegate {
static let shared = WatchSessionManager() // 싱글톤 인스턴스 생성
@Published var alertMessage: String = " " // 기본 메시지
@Published var isAlerting: Bool = false // 알림 상태 확인
static let shared = WatchSessionManager()

@Published var alertMessage: String = "인식중"
@Published var isAlerting: Bool = false

private override init() {
super.init()

if WCSession.isSupported() {
WCSession.default.delegate = self
WCSession.default.activate()
}
}

// iOS에서 경고 메시지를 수신하는 메서드

func alertImageName() -> String {
switch alertMessage {
case "Carhorn":
return "Car"
case "Siren":
return "Siren"
case "Bicyclebell":
return "Bicycle"
default:
return "issue"
}
}

// iOS에서 sendMessage로 데이터 수신
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
if let alert = message["alert"] as? String {
DispatchQueue.main.async {
self.showAlert(with: alert)
}
}
}

// 이미지 이름을 반환하는 메서드
func alertImageName() -> String {
switch alertMessage {
case "Carhorn":
return "Car" // carhorn 이미지 이름
case "Siren":
return "Siren" // siren 이미지 이름
case "Bicyclebell":
return "Bicycle" // bicycle 이미지 이름
default:
return "exclamationmark.triangle.fill" // 기본 알림 아이콘

// iOS에서 updateApplicationContext로 데이터 수신
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
if let alert = applicationContext["alert"] as? String {
DispatchQueue.main.async {
self.showAlert(with: alert)
}
}
}

// 3초 동안 알림 표시 후 기본 상태로 복구
func showAlert(with message: String) {
alertMessage = message
isAlerting = true
WKInterfaceDevice.current().play(.notification)

// 강한 진동 알림 발생
playUrgentHapticPattern()

// 3초 후에 기본 상태로 복구
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.resetAlert()
}
}

// 긴급 상황을 위한 강한 진동 패턴
func playUrgentHapticPattern() {
// 반복 횟수 및 간격 설정
let repeatCount = 30 // 진동 반복 횟수
let interval: TimeInterval = 0.05 // 반복 간격 (0.1초)

// 반복적으로 강한 진동을 재생하는 패턴
for i in 0..<repeatCount {
DispatchQueue.main.asyncAfter(deadline: .now() + (interval * Double(i))) {
WKInterfaceDevice.current().play(.failure) // 강한 피드백을 주는 진동
}
}
}

// 기본 상태로 복구하는 메서드
func resetAlert() {
alertMessage = "인식중"
isAlerting = false
}

// WCSession 활성화 완료 시 호출되는 메서드

func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("애플워치 - WCSession 활성화 완료. 상태: \(activationState.rawValue)")
if let error = error {
print("애플워치 - 활성화 오류: \(error.localizedDescription)")
}
}

func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
if let highestConfidenceSound = applicationContext["highestConfidenceSound"] as? String {
DispatchQueue.main.async {
self.showAlert(with: highestConfidenceSound) // 수신한 소리를 알림으로 표시
print("애플워치 - applicationContext 데이터 수신: \(highestConfidenceSound)")
}
print("WCSession 활성화 오류: \(error.localizedDescription)")
} else {
print("WCSession 활성화 성공: 상태 \(activationState.rawValue)")
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"colors" : [
{
"color" : {
"platform" : "ios",
"reference" : "groupTableViewBackgroundColor"
},
"idiom" : "universal"
}
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"images" : [
{
"filename" : "Icon .png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions hearo/LiveActivity/Assets.xcassets/Icon.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "Icon.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Icon 1.svg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Icon 2.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
26 changes: 26 additions & 0 deletions hearo/LiveActivity/Assets.xcassets/Icon.imageset/Icon 1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions hearo/LiveActivity/Assets.xcassets/Icon.imageset/Icon 2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions hearo/LiveActivity/Assets.xcassets/Icon.imageset/Icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"colors" : [
{
"color" : {
"platform" : "universal",
"reference" : "labelColor"
},
"idiom" : "universal"
}
],
Expand Down
2 changes: 0 additions & 2 deletions hearo/hearo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,6 @@
INFOPLIST_KEY_LSApplicationCategoryType = "";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "A message that tells the user why the app is requesting access to the device’s microphone.";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
Expand Down Expand Up @@ -1052,7 +1051,6 @@
INFOPLIST_KEY_LSApplicationCategoryType = "";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "A message that tells the user why the app is requesting access to the device’s microphone.";
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,21 @@
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "35B5EB06-74AC-48F5-97F1-7808B582A78F"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "hearo/Sources/Presentations/Working/ViewModel/WorkingViewModel.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "67"
endingLineNumber = "67"
landmarkName = "handleAppForeground()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
Loading

0 comments on commit 4975cc6

Please sign in to comment.