Hi .ᐟ 아임웬디~
3주차 글 작성을 맡아 어떤 글을 쓸까 고민하다가.. 꽤나 애먹었던 Watch Connectivity에 관해 써볼까 한다
Mini Challenge 2 에도 같은 팀이었던 우리는 리틀하이커 라는 등산 어플을 개발
했는데
하는 중인데…. 그 중 워치에서 수집한 데이터를 아이폰으로 보내야 하는 작업이 있었다.ᐟ
워치 - 아이폰간 데이터를 전송하려면 cloudKit이나 Watch Connectivity를 사용해야 하는데 그 중에서 Watch Connectivity 를 사용하기로 했다.
이 와취커넥티뷔리에 대해 말해보려고 한다.ᐟ 레쓰고~
Watch Connectivity가 뭘까?
https://developer.apple.com/documentation/watchconnectivity → 공식문서
- ios - watch 간 데이터 전송 프레임워크
- 데이터 혹은 파일을 전송할 수 있고 파일 전송은 백그라운드에서 이뤄짐
- 워치와 폰 모두 활성상태일 때 라이브 통신도 가능
대충은… 이해하겠는데 어떻게 하라고..?🧐
그래서 일단 샘플코드를 다운받았다
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
스택오버플로우의 도움을 받아 파일전송이 완료되면 완료 메세지를 다시 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 |
---|