PWA를 위해 아이콘을 생성하다가 든 의문은 다음과 같았다.
manifest의 icons에도 아이콘을 작성하고, index.html에도 link를 추가하는 이유가 뭘까?
이에 대해서 파고파고 들어가다가 그냥 아예 PWA의 아이콘과 스플래쉬 화면에 대해서 정리를 해야겠다 싶어서 쓰는 포스팅. 만약 다 제치고 적용하는 것만 보려면 아래로!
일단 궁금증부터 풀어보면, iOS와 Android에서 작동하는 게 다르기 때문에 해주는 것. Android는 manifest 파일 하나만으로 앱 아이콘 및 앱 스플래쉬 화면이 자동으로 지원해주는데 iOS는 따로 지정해줘야 한다. 역시 애플이 애플했다
manifest의 icons 목록에 추가해주면 된다. 기기 해상도에 대응해주기 위해 여러 사이즈를 추천해주는데, 하나만 할거면 512x512 사이즈를 권장한다. 여러 사이즈를 넣어주면 기기가 알아서 적절한 걸 골라서 쓴다.
이때, 마스크 아이콘이라는 용어가 나온다. 안드로이드 등 특정 기기에서는 아이콘의 모양을 동그라미나 다른 모양으로 마스킹해서 보여준다. 문제는 그 모양 그대로 자르기 때문에 원하는 아이콘이 안 나올 수 있다. 이를 방지하기 위해서 padding 값을 넣어준 게 마스크 아이콘이라고 하더라~ 이 경우 purpose 속성을 지정해주면 된다.
"icons": [ { "src": "/icons/512.png", "type": "image/png", "sizes": "512x512" }, { "src": "/icons/1024.png", "type": "image/png", "sizes": "1024x1024" }, { "src": "/icons/512-maskable.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" }, ]
우리의 애플은 따로 다뤄줘야 한다. manifest 파일로는 아이콘을 보여주지 않기 때문에, 아래와 같은 meta 태그를 지정해주어야 한다.
<link rel="apple-touch-icon" href="touch-icon-iphone.png"> <link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad.png"> <link rel="apple-touch-icon" sizes="180x180" href="touch-icon-iphone-retina.png"> <link rel="apple-touch-icon" sizes="167x167" href="touch-icon-ipad-retina.png">
참고: Apple의 iOS는 Web Clip 또는 시작 화면 플레이스 홀더에 사용할 아이콘을 고를 때, 다른 모바일 브라우저와는 달리 icon 링크 유형은 물론 sizes 특성을 사용하지 않습니다. 대신, 각각에 대응하는 비표준 apple-touch-icon과 apple-touch-startup-image를 사용합니다.
...이러한 플랫폼에서 PWA를 홈 화면 웹 앱이라고도 합니다.(iOS)
Safari에서는 웹 클립이라는 네이티브 기술을 사용하여 운영체제에서 PWA 아이콘을 만듭니다.
iOS도 마찬가지로, 어느 정도 mask가 된 상태로 표시가 되기 때문에 padding을 주어야 한다. 또, 마찬가지로 적절한 사이즈를 선택해서 사용하는데 얜 적절한 사이즈가 없으면 해당 사이즈 기준 위 아래를 선택한다구 한다.
If there is no icon that matches the recommended size for the device, the smallest icon larger than the recommended size is used. If there are no icons larger than the recommended size, the largest icon is used.
디바이스의 권장 크기와 일치하는 아이콘이 없는 경우 권장 크기보다 가장 작은 아이콘이 사용됩니다. 권장 크기보다 큰 아이콘이 없는 경우 가장 큰 아이콘이 사용됩니다.
웹도 놓치지 말고 해줘야 한다. 웹은 파비콘 favion을 적용해주면 된다.
<link rel="icon" type="image/png" sizes="192x192" href="icons/android-icon-192x192.png" /> <link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png" /> <link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png" /> <link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png" />
manifest 파일만 잘 작성해주면 알아서 해준다. 작성해야 할 속성은 다음과 같다.
우리의 애플? 역시 기대를 저버리지 않는다. 따로 link 태그를 걸어서 적용을 해줘야 하는데, 문제가 있다.
문제는 시작 이미지의 창 크기가 PWA가 열릴 때 보이는 것과 정확히 일치해야 한다는 점입니다. 따라서 iOS 및 iPadOS 기기마다 다른 이미지가 필요합니다. 가로 모드/세로 모드로 열거나 멀티태스킹 모드 (예: 화면의 1/3, 1/2 또는 2/3)로 PWA를 렌더링하는 등 iPad에서 더 많은 상황을 처리해야 합니다.
경고: 화면 정의, 방향, 멀티태스킹 모드를 결합한 가능한 모든 옵션을 제공하려는 경우 HTML에서 만들고 연결해야 하는 서로 다른 이미지가 25개 이상 생깁니다.
레전드. 물론 ,, 이 단순 작업을 위해 제공하는 generator가 존재한다. 이걸 쓰면 된다.
먼저 아래 사이트로 들어가서 기본 이미지를 생성해주자. (pwa-asset-generator는 뭔가 이용하기 불편하더라...)
https://progressier.com/pwa-icons-and-ios-splash-screen-generator
여기가 좋은 게, 위에서 언급한 maskable 아이콘을 직접 만들 수 있게 해준다.
다 되면 이렇게 이미지들이 뜨는데, 위에 있는 Download Bundle을 클릭해서 zip 다운로드 해주고, splash_screens 폴더를 자신의 프로젝트에 붙여넣어주자. (주의! splash_screens 안에 또 같은 이름의 폴더가 있음.)
그 다음, readme.txt 파일에 있는 link 태그들을 index.html의 head에 붙여넣어주면 iOS 스플래쉬 화면 끝!
이건 애플의 버그같은데,, 가로모드로 최초 실행시엔 다음과 같이 나온다. (세로 모드는 잘 됨)
하지만 이전에 다른 PWA앱 하나를 켜놓고, 다시 들어가면 정상적으로 출력된다.
이거 때문에 진짜 개고생했는데 .. 그냥 애플의 자체 버그인 것 같다.
Portait는 정상적으로 잘 나오는데, landscape로 하면 portait 화면을 가져와 강제로 늘리는 버그가 있다고 한다. 이건 아주 오래 전부터 있었던 버그라던데,, (apple splash screen stratched) 대응을 한다고 해놓고 아직까지 안 하고 있는 듯. 이자식들이!
나는 asset generator가 이상하게 만들어준 건 줄 알았는데... 미안하다!
Splash 이미지를 먼저 생성해준 이유가, 저 사이트로 생성을 하면 Maskable Icon도 만들어주기 때문! 이제 이걸 가지고 아래의 사이트에 들어가자.
https://www.favicon-generator.org/
파일을 업로드 하고 위와 같이 설정을 하고 Create Favicon을 눌러주면~
아주 예쁘게 iOS의 아이콘과 favicon, 그리고 manifest까지 작성해준다. 마찬가지로 Download the generated favicon을 눌러 다운로드한 asset들을 자신의 프로젝트에 넣어주고, link태그들을 index.html에 붙여넣어주면 된다.
manifest에서 생성되는 density는 없는 속성이다(!) 이걸 다 없애주고, "purpose": "maskable"
를 각각 넣어주자.
히야! 예쁘다.
그런데 위위의 사이트에서 만든 아이콘으로 Favicon을 적용하면 이렇게 보인다.
Oopps,,, 개못생겼다. 그래서 배경이 투명한 Favicon용으로 패딩 없이 하나 다시 만드는 걸 추천한다.
한결 낫군..
이제 PWA를 위한 Manifest를 작성하면 된다. 아래 사이트에서 필요한 정보를 기입하자.
https://progressier.com/pwa-manifest-generator
필요한 것만 쇽쇽쇽 넣고 icons를 제외한 나머지를 기존의 manifest 파일에 덮어씌우면 된다.