Tech

[Watch Connectivity] 를 통한 데이터 전송 및 어려웠던 부분 🆘

웬디 2024. 9. 20. 21:11

Hi .ᐟ 아임웬디~

3주차 글 작성을 맡아 어떤 글을 쓸까 고민하다가.. 꽤나 애먹었던 Watch Connectivity에 관해 써볼까 한다

 

Mini Challenge 2 에도 같은 팀이었던 우리는 리틀하이커 라는 등산 어플을 개발

했는데

하는 중인데…. 그 중 워치에서 수집한 데이터를 아이폰으로 보내야 하는 작업이 있었다.ᐟ

워치 - 아이폰간 데이터를 전송하려면 cloudKit이나 Watch Connectivity를 사용해야 하는데 그 중에서 Watch Connectivity 를 사용하기로 했다.

 

이 와취커넥티뷔리에 대해 말해보려고 한다.ᐟ 레쓰고~

Watch Connectivity가 뭘까?

https://developer.apple.com/documentation/watchconnectivity → 공식문서

  • ios - watch 간 데이터 전송 프레임워크
  • 데이터 혹은 파일을 전송할 수 있고 파일 전송은 백그라운드에서 이뤄짐
  • 워치와 폰 모두 활성상태일 때 라이브 통신도 가능

대충은… 이해하겠는데 어떻게 하라고..?🧐

그래서 일단 샘플코드를 다운받았다

https://developer.apple.com/documentation/watchconnectivity/transferring-data-with-watch-connectivity

UIKit 이잖아…………..? 나는 SwiftUI밖에 모르는 바보인데…

그래도 잘 열심히 최선을 다해서 이해해보려고 노력해보았다.

문서에 나와있는대로 info.plist의 설정값을 바꾸고 실기기에 빌드해서 테스트해보면서 어떻게 코드가 동작하는지 이해하려고 했다~

그래서 예시 파일에 있는 FileTransferObservers 클래스 파일을 뽀려왔다~

근데 이건 파일전송객체를 감시하기 위한 클래스 파일이고 실제 파일전송과는 무관했다. (아무래도.. 그냥 바보인가? )

// 파일전송
func transferFile(_ fileUrl: URL, _ metadata: [String: Any]?) {
    let fileTransfer = self.session.transferFile(fileUrl, metadata: metadata)

    fileTransferObservers.observe(fileTransfer) { _ in
        self.logProgress(for: fileTransfer)
    }
}

이런 식으로 파일전송을 작성했는데, 파일이 실제로 전송되는건 self.session.transferFile 에서 이루어지고, 해당 전송이 일어나는지 감시하는 부분이 fileTransferObservers.observe(fileTransfer) { _ in ~ 이 부분이다.ᐟ 파일이 전송되는 진행율을 감시하면서 완료됐을때의 동작을 추가해줄 수 있다.

파일 전송에 관한 부분은 https://developer.apple.com/documentation/watchconnectivity/wcsession/transferfile(_:metadata

이 부분을 참고하면 된다 :)

고 하면 무책임하니까

일단 Data 형식을 파일로 만든 다음

// jsonData를 파일형식으로 만들고 pathURL 생성
func makeFile(_ jsonData : Data, _ fileName: String) -> URL? {
    let fileManager = FileManager.default
    let timeManager = TimeManager()
    if let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {

            //저장할 파일명은 여기서 지정
        let fileURL = documentDirectory.appendingPathComponent("\(fileName)_\(timeManager.formatToYmdHis()).json")
        do {
            try jsonData.write(to: fileURL)
            return fileURL
        } catch {
            print("Failed to write file: \(error.localizedDescription)")
        }
    }
    return nil
}

위에 파일전송 예시코드에 나와있는대로 WCSession의 transferFile로 전송하면 된다.

`let fileTransfer = self.session.transferFile(fileUrl, metadata: metadata)`

트러블슈팅팅팅팅탱탱탱탱🍳

트러블 1. 전송 크기 이슈

리틀하이커는 기본 하산을 도와주는 등산어플 이다. 우리는 초단위로 심박수, 고도 등등의 데이터를 수집하는데, 등산은 몇시간 동안 진행되니 데이터의 양이 정말 많을 수 밖에~ .ᐟ WatchConnectivity에는 문자열로 데이터를 보내는 형식인 sendMessage와 파일로 전송하는 transferFile이 있는데, sendMessage 로 텍스트 전송하면 최대 용량 제한이 있어 데이터를 잘라서 몇십번의 통신을 해야했다😱 그래서 작업 중에 깨닫고 파일전송으로 데이터 통신하기로 바꿨다.

사실 이 이슈를 깨닫는데까지도 꽤 많은 시간을 할애했기 때문에…

우리… 거의 정상에 다 왔는데 너무 많이 남은 것 같다고 하산하고 새로운 산을 찾는건 아닐까?

근데 사실 거의 정상인 줄 알았는데 아직 남은게 히말라야급일수도 있다

하산하고 새로 올라가는 길이 동산일 수 있어서 더 빠른 길일 수 있다

뭐 이런 얘기를 하며 파일전송으로 바꿔서 결정했던 것 같다.

사실 지금 시점에 보면… 남은게 히말라야였던 건 맞는데 하산하고 다시 올라가는 산이 동네 뒷산은 아니었나봉가

트러블 2 didFinish가 호출되지 않는 이슈

파일전송이 완료되었는데 완료가 되었는지 아닌지 알 수가 없는 이슈가 있었다. didFinish가 호출되지 않기 때문. 이 문제는 애플 포럼에도 올라와있는 이슈였다.

https://developer.apple.com/forums/thread/751623

https://stackoverflow.com/questions/78569322/missing-wcsessiondelegate-didfinish-callback-transferring-file-from-watchos-to-i

스택오버플로우의 도움을 받아 파일전송이 완료되면 완료 메세지를 다시 watch 에 보내는 방식으로 수동구현했다. 정말 감사하다.

for fileTransfer in session.outstandingFileTransfers {
       if (fileTransfer.progress.isFinished) {
               fileTransfer.cancel()
         }
 }

근데 지금와서 보니까 파일전송이 제대로 안 되는 이슈와는 관계가 없는 것 같기도 하다^.^ 또르륵

그래도 파일 전송완료 여부를 감시하다가, 완료되면 둘 간의 연결을 끊을 수 있으니까~ 어쨌든 좋은 게 좋은거라고 생각하자.ᐟ

트러블 3 로그가 출력되지 않는 이슈

파일전송통신은 시뮬레이터로 디버깅이 안 되기 때문에 실기기에 빌드했어야 했다. 근데 ios에 데이터가 제대로 전송됐는지 확인하고 싶어도 워치와 핸드폰에 동시에 빌드하기 위해서는 xcode 프로젝트에서 워치 타겟으로 빌드해야했다. but? watch로 빌드하면 폰에서 쓴 print는 출력되지 않아 디버깅이 안되는 이슈가 있었다.

그렇다고 워치타겟/ 핸드폰 타겟으로 따로따로 빌드를 하면 두개가 연결되지 않았고

해결법은.ᐟ.ᐟ 바로바로 ?.ᐟ (두구두구)

iphone에 다짜고짜 출력해보기.ᐟ (WOW 정말 대단해)

 

xcode가 아닌 다른 에디터를 하늘에서 누군가 내려줬으면 좋겠다…

트러블 4 파일이 올바르지 않은 이슈(휴먼이슈)

정말 오래 끙끙댄 문제였는데 json 형식으로 안보내고 그냥 다짜고짜 글자라도 보내보겠다고 “aaa” 이런거 입력해놓고 json 디코딩하는데에서 디코딩이 제대로 안된다고 함^^ 그래놓고 파일 전송할때마다 항상 같은 크기로 전송된다고 뭔가 이상하다고 함.. 정말 써놓기 민망하지만.ᐟ 이런 실수는 종종 있는 일이라 한번 더 사람(스스로)을 의심해 보라는 이유로 공유해본다 ㅎㅎㅎㅎㅎ

그래도

긴~~~~~~~~~~우당탕탕 끝에 데이터 전송이 되는 걸 확인했다.ᐟ

사실 아직.. 다 해결된 건 아니고 몇시간의 등산을 진행하고 나서 대용량의 데이터가 제대로 파일화 되서 가공이 되는지 확인해야 하는 작업이 남았다^_^

네버엔딩 다람이.

화이팅 다람이

화이팅 구짐현커(구 짐승들 현 커맨드알)

 

 

참고

https://developer.apple.com/documentation/watchconnectivity 공식문서

그리고 친구비를 낸 gpt 선생님

'Tech' 카테고리의 다른 글

[SwiftUI] Swift Charts 시작하기  (3) 2024.09.17