-
Safari Web Extensions 탐구해보기 (with. WWDC 20)MacOS 2023. 4. 6. 10:56
안녕하세요. 그린입니다🍏
이번 포스팅부터 몇주간은 조금 특별한걸 해볼까해요.
바로 사파리 확장 프로그램을 만들어볼까 합니다🙋🏻
그래서 먼저 WWDC 20에서 Safari Web Extensions에 대해 발표가 있어서 오늘 그거부터 학습해보려합니다🙌
아예 macOS 개발이나 Safari Web Extensions 요 쪽 개발에는 지식이 전혀 없어 제가 느끼기에 먼저 배우면 좋을것 위주로 학습중입니다!
많은 도움 및 지적 부탁드립니다🙏🏻
기존 Safari의 확장 에코 시스템
Safari 14 전 버전들에서 확장 에코 시스템 방식에 대해 설명합니다.
Content Blockers
👉🏻 iOS / macOS에서만 작동하며 이는 속도와 유저 개인정보보호를 위해 고안되었습니다.
Share Extensions
👉🏻 iOS / macOS에서 가능하며 웹 페이지의 자바스크립트 실행을 할 수 있으며 데이터를 해당 앱 익스텐션에 전달할 수 있습니다.
Safari App Extensions
👉🏻 macOS에서 사파리 앱 익스텐션이 가능합니다.
이러한 것들의 특징은 네이티브 개발자라면 아주 좋죠!
왜냐면 이미 Swift나 Object-C에 친숙할테니까요.
이미 네이티브 기술들을 사용하여 확장 구현이 되어 있습니다.
그런데 만약 네이티브 개발자가 아닌 웹 개발자인데 사파리 확장 프로그램을 만들고 싶다면?
접하지 않은 언어를 공부해야하고 포기하게 만들게 됩니다.그래서 자바스크립트, HTML, CSS에 친숙한 웹 개발자들도 쉽게 만들 수 없을까? 라는 생각을 갖게 됩니다.
아마 주로 많이 사용되는 웹 브라우저에서 확장 프로그램의 경험을 다들 가지고 있으실겁니다.
그런데 또 사파리 지원을 위해 네이티브 코드로 다시 작성하는것을 원치 않을거에요.
그럼 이제 어떻게 어떤걸 지원할까요 사파리가?
달라진 Safari Web Extensions
Safari 14버전 부터 macOS에서 자바스크립트를 통해 웹 익스텐션 개발을 지원해줍니다!
뿐만아니라 HTML, CSS까지 주요하게 사용할 수 있죠.
기존 Swift 언어에 익숙한 iOS/macOS 개발자에게는 별거 아닐 수 있지만 웹 개발자들에게는 아주 희소식이죠.
웹 개발 모델을 따르면서 호환성도 챙겼습니다.
이렇게 되면 다른 브라우저들하고 같은 확장 모델과 API들을 사용하여 서로 양립할 수 있게 됩니다.
그럼 기존 확장들은 어떻게 변환되어 사용할 수 있을까요?
기존 확장 컨버팅하기
우선 아래와 같이 명령어를 실행해줍니다.
xcrun safari-web-extension-converter [options] path/to/extension
한번만 돌려주면 됩니다.
그럼 요런식으로 정보가 올바른지 묻습니다.
그리고 512x512나 1024x1024의 아이콘을 추가해줍니다.
마지막으로 Xcode Project에 확장을 위한 개발에 필요한 파일을 추가해줍니다.
그러고 실행을 하면 사파리가 열릴것인데 아직 추가가 되지 않았을거에요.
이는 사파리 환경설정에서 Advanced로 들어가 가장 하단 "Show Develop menu in menu bar"를 클릭해줍니다.
한국어로 설정되있다면 고급 > 메뉴 막대에서 개발자용 메뉴 보기 버튼입니다.
그 다음 해당 프로그램을 허용해야 하기에 상단 Develop > Allow unsigned extensions and authenticate를 클릭해줍니다.
한국어로 되어 있다면 개발자용 > 서명되지 않은 프로그램 허용 메뉴입니다.
그럼 암호 인증을 통해 허용이 될것입니다.
그 다음으로 다시 확장 프로그램으로 오면 추가하고자 했던 테스트용 확장 프로그램이 나타나게 됩니다!
(저는 아직 만든게 없어서 Bing AI 사용을 위해 빙 확장 프로그램만 추가되어있네요ㅎㅎ..)
이제 아이콘 왼쪽 체크박스를 체크해주게 되면 아래와 같이 도메인 주소창 왼쪽 방패 아이콘 옆에 사용하고자 하는 확장 프로그램이 활성화되어 나타나게 됩니다.
이제 그럼 어떻게 달라진 사파리 웹 익스텐션을 만들어내는지 같이 해보시죠!
Create Safari Web Extension
우선 프로젝트를 만들어줍시다!
먼저 아래와 같이 macOS를 통해 프로젝트 앱을 하나 생성해요.
앱이 생성되면 확장 타겟을 만들어줘야합니다.
이는 File > New > Target 메뉴를 통해 접근할 수 있습니다.
요렇게 타겟에서 Safari Extension을 선택하고 생성해줍니다.
밑에 보이는 Safari Extension App 타겟은 단순 사파리에 심어지는 확장 프로그램뿐 아니라 앱으로도 만들 수 있습니다.
그럼 아래와 같이 해당 익스텐션이 생기며 구조를 볼 수 있어요.
크게 구조를 보시면 정보를 담은 manifest 파일과 background / content / popup 파일로 구성되어 있습니다.
여기서 조금만 더 자세히 말해볼께요.
manifest 파일은 만드는 확장 프로그램의 전체적인 정보를 가진 파일입니다.
네이밍/아이콘 및 동작할 도메인 등 다양한 정보가 담겨있죠.
그 다음으로 background 파일은 백그라운드에서 도는 즉, 메시지 수신과 같은 이벤트가 발생할때 동작하는 스크립트입니다.
content 파일은 실제 웹의 확장 기능을 제공해줍니다.
popup은 확장 프로그램의 UI입니다.
자 여기까진 아주 쉽게 따라할 수 있습니다.
그럼 더 나아가보시죠!
우선 확장 프로그램에 사용될 아이콘부터 변경해볼께요.
요 images 리소스에 원하는 아이콘을 넣어주시면 됩니다.
저는 초록 사과를 넣었어요!
그 다음 manifest 파일을 수정해볼께요.
{ "manifest_version": 3, "default_locale": "en", "name": "__MSG_extension_name__", "description": "__MSG_extension_description__", "version": "1.0", "icons": { "48": "images/Icon-48.png", "128": "images/Icon-128.png", "256": "images/Icon-256.png", "512": "images/Icon-512.png" }, "background": { "service_worker": "background.js" }, "content_scripts": [{ "js": [ "content.js" ], "matches": [ "*://*.wikipedia.org/*" ] }], "action": { "default_popup": "popup.html", "default_icon": { "16": "images/Icon-16.png", "32": "images/Icon-32.png", "48": "images/Icon-48.png", "72": "images/Icon-72.png" } }, "permissions": [ "activeTab" ] }
요렇게 아까 심어준 아이콘으로 대체해줍니다.
또한 content 스크립트에서 특정 도메인에 대해 지정해줄 수도 있고 아니면 모든 url에 대해 허용하고 싶다면 아래와 같이 변경해주면 됩니다.
"content_scripts": [{ "js": [ "<all_urls>" ], "matches": [ "*://*.wikipedia.org/*" ] }]
permission을 보면 접근 권한을 뜻하는데요.
activeTab을 통해 실제 활성화된 탭에서만 동작하도록 할 수 있고 또 여러가지 허가 조건을 달 수 있습니다.
위에 언급되진 않았지만 WWDC 20에서는 optional_permissions라는 조건도 달 수 있습니다.
선택적으로 권한을 인가해줄 수 있죠.
그 다음으로 content script를 수정해보겠습니다.
저는 WWDC 20의 예제처럼 위키피디아에서 Green이라는 글자를 초록 사과로 치환하도록 수정하는 스크립트를 구현해볼께요.
browser.runtime.sendMessage({ greeting: "hello" }).then((response) => { console.log("Received response: ", response); }); browser.runtime.onMessage.addListener((request, sender, sendResponse) => { console.log("Received request: ", request); }); (() => { function getText (node) { if (node.hasChildNodes()) { node.childNodes.forEach(getText); } else if (node.nodeType === Node.TEXT_NODE) { if (node.textContent.includes("Green")) { node.textContent = node.textContent.replaceAll("Green", "🍏"); } } } getText(document.body); })();
이제 해당 웹 페이지 로드하고 확장 프로그램을 돌리면 요 기능이 작동하게 됩니다.
다음으로 popup 파일을 수정해보죠!
<HTML>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="popup.css"> <script type="module" src="popup.js"></script> </head> <body> <strong>Green is Green</strong> </body> </html>
<CSS>
:root { color-scheme: light dark; } body { width: 100px; padding: 10px; font-family: system-ui; text-align: center; } span { display: block; margin: auto; margin-top: 10px; width: 50px; height: 50px; border-radius: 50%; background-color: #fff; box-shadow: 0, 0, 10px rgba(0, 0, 0, .5); } span::before { content: "🍏"; line-height: 50px; } @media (prefers-color-scheme: dark) { span { background-color: #000; } }
이 구성들은 원하는 UI에 맞게 하시면 됩니다!
자 그럼 이제 코드 구현 및 수정은 끝났습니다.
빌드하고 테스트 해볼까요?Extension 적용해보기
확장 프로그램을 보시면 아래와 같이 우리가 만든 Extension 프로그램이 생겼어요!
이제 체크해주면 도메인 옆에 사용할 수 있게 나타납니다.
해당 프로그램 아이콘을 클릭하면 1일만 허용할지 항상 허용할 지에 대해 선택합니다.
그럼 이제 위키피디아에서 Green이라는 글자는 다 초록 사과로 변경되는걸 볼 수 있습니다🎉
추가로, 해당 아이콘을 클릭하면 아래와 같이 아까 popup을 꾸며준 글씨가 나타납니다! (html 파일에서)
자 아주아주 간단하게 쉬운 Extension을 만들어봤습니다!
마무리
아예 처음 해보는 학습이라 쉬움에도 불구하고 많이 버벅였네요!
아직 사파리에서는 크롬만큼 많은 확장 프로그램이 없는것 같아 한번 만들어보기 위한 초석으로 학습을 진행해봤어요.
매일 iOS 개발만 하다가 새로운걸 배우니 너무 재밌네요🙌
디버깅이나 앱하고의 메시지 소통 같은 것도 WWDC 영상에 존재하는데 이는 조금 더 알아보겠습니다!
위 실습한 예제 프로젝트는 아래 깃헙 레포를 참고하셔도 좋습니다😃
https://github.com/GREENOVER/playground/tree/main/safariTest
[참고 자료]
'MacOS' 카테고리의 다른 글
Tailor macOS windows with SwiftUI (feat. WWDC 2024) (77) 2024.07.25 Safari Web Extensions 탐구해보기 (2) (12) 2023.04.10 iTerm2 설치 및 사용 (0) 2021.04.05