새로 시작한 위젯을 하나하나 만들어가며..!
어느정도 통신을 하고, 화면을 그리도록 만들었습니다!
그런데 화면을 그리면서 크게 세 가지 문제점이 있었는데
1. 위젯이 원래 앱에서 저장된 파일 URL 경로를 찾지 못한다
2. 위젯이 큰 사이즈의 사진을 지원하지 않는다는 점과
3. 유저가 설정한 사진에 따라 날씨 표시되는 부분의 레이아웃이 변경되는 문제였습니다.
우선 1번으로 스트레스를 많이 받았는데요...
앞서 NotificationCenter를 사용할때
realm으로 저장한 사진을
FileManager로 URL을 저장하고,
알림 설정 트리거를 보낼때
URL을 같이 보내 사진을 접근할 수 있도록 만들었습니다.
그 방법 그대로 사용을 했는데
이상하게 위젯에서는 파일URL에 접근을 잘 못했습니다ㅠㅠ
분명 원래 앱에서 imageURL 저장을 성공하고, 알림이 올때 imageURL에 접근해 사진도 로딩하지만
위젯에서 접근할때는 파일이 존재하지 않는다고 거짓말을 하네요..후
그래서 고민을 많이다하가...
AppGroup을 통해 realm 데이터를 AppExtension에서 접근할 수 있다는 글을 보게 됩니다..!
참고 글
https://hururuek-chapchap.tistory.com/202
진짜 저번에 CoreData가 잘 안되서
하루 날 잡고 realm으로 리팩토링을 싹 했었는데
그게 신의 한 수 였습니다!! 역시 realm 최고~!
우선 AppGroup을 설정하고,
AppDelegate에 설정한 AppGroup를 포함해 공유 컨테이너를 설정해줍니다
그리고 Widget 부분에서
편하게 사용하기 위해 realmManager를 만들어줍니다.
그리고 Widget 뷰 부분에서 불러주면~!
잘 될 줄 알았지만
1920 * 2880의 사진 사이즈가 크다고 안되네요..위젯에 표시되는 사진은 크기를 조정해야 되는데
기존에 이미지 줄이는 것과 같은 방식으로
.resizable()
.frame() 설정을 해줘도 앱에 표시되는 크기가 작아지는거지
파일 자체의 크기가 줄어드는 것은 아니라 해결이 되지 않았습니다.
그래서 파일 사이즈 자체를 줄여주는 함수를 만들고, (이 부분은 GPT의 도움을 받았습니다!)
realm으로 사진 Data를 불러오니
쨘! 이렇게 잘 나오는 모습을 볼 수 있었습니다!
이전에 이 방법을 몰라서
NotificationCenter에 사진 데이터 URL과
앱의 위치 정보 등을 복잡하게 전송했었는데
이 방법으로 간결하고, 효율적으로 바꿀 수 있을 것 같아서 설렜습니다!
NotificationCenter도 추후에 리팩토링하는 과정도 정리해보겠습니다!
제 폰에 설치한 위젯에서
세로 이미지를 설정했을때
의도한대로 레이아웃이 잘 연동되는 것을 볼 수 있었는데요
이렇게 시뮬레이션에서 설치한 위젯은
의도한 것 처럼 레이아웃이 설정되지 않아서 왜그럴까..하고 원인을 한참 비교해면서 찾아보니
세로가 아닌 가로 사진을 설정하고,
이미지를 .aspectRatio(contentMode: .fill)로 설정하면
화면에 맞게 사진이 늘어나면서 ZStack위에 올려둔 컨텐츠들도 같이 레아아웃 밖으로 밀려나게 되는 것이었습니다!
역시 어느하나 쉬운게 없네요ㅎㅎ
프레임을 강제로 설정해보기도 하고,
컨텐츠를 중간으로 옮겨보기도 했는데 이상해서 고민을 하다가
위젯패밀리로 분기처리해서 각각 사이즈를 줘야하나..하고 위젯 사이즈도 검색해보았는데
생각보다 종류가 다양해서 이 방법은 진짜 안돼...하고 고민하고 있는 와중에
최근에 앱스쿨 3기 보조강사를 같이 시작한!
태영이랑 강의 중간에 잠깐 시간이 생겨서 이야기해봤는데
GeometryReader를 적용해보면 어떻겠냐는 아이디어를 줘서 적용해보았습니다!
이전 앱스쿨에서 아이폰과 아이패드 모두 돌아가는 앱을 GeometryReader를 사용해서 연동했었는데
오랜만에 SwiftUI를 하니 기억을 못했네요ㅎㅎ
기억을 더듬어가면서 적용해봤는데..!
쨘..! 이렇게 위젯 사이즈마다 GeometryReader가 대응해줘서
원하는 위치로 컨텐츠를 배열할 수 있었습니다! 와~!
최종적으로 정리한 코드입니다!
body부분을 최대한 깔끔하게 두는 것을 좋아해서
body 안에 들어가는 부분은 extension + 연산 프로퍼티로 따로 정리하는 편입니다.
이렇게요! 깔끔하고 유지보수가 쉬워서 좋아하는 방식입니다:)
그리고 .large 사이즈의 컨텐츠 위치가 애매해서
WidgetFamily의 사이즈가 .large일때만 Spacer를 넣어서 날씨 컨텐츠를 위로 올려주었습니다.
위젯마다 레이아웃을 다르게 배치하고싶으면
이런식으로 분기처리해서 뷰를 그려주어도 좋을 것 같아요!
저는 사진을 크게 보는것도 좋아해서 지금도 괜찮다고 생각하지만
너무 비어보인다는 의견이 있어서
나중에 기회가..된다면 주간날씨나 시간별 날씨를 아래에 배치할 예정입니다!
그리고 유저가 날씨요정을 선택하지 않거나
취소하는 경우에는
위젯에 현재 날씨에 맞는 배경화면을 띄워주는걸로 바꿨습니다.
저는 당연히 최애를 설정해서 사용할거지만
설정하지 않고 쓰시는 분들도 많으신 것 같더라구요
이렇게 적용하고보니 배경화면 자체도 예뻐서 마음에 들어요!
부디 위젯을 적용한 첫 2.0 메이저 업데이트가 성공하길 바라며 마무리하겠습니다.
다들 화이팅~!