
유용한 사이트
- FontAwesome Font Awesome
。Web상에서 많이 활용되는Icon을Vector형태로 제공하는 서비스.
▶ Web application 구축 시 Icon을 하나씩 생성하는게 아닌, 코드를 가져다 활용 시 바로 사용이 가능하므로 편리함.
。Font Awesome CDN:
<script src="https://kit.fontawesome.com/User번호.js" crossorigin="anonymous"></script>
.
FontAwesome/Icon
。 해당 사이트에서 원하는 icon을 선택 후 icon에 할당된 html tag를 활용.
ex)<i class="fa-solid fa-camera"></i>
- Lorem picsum Lorem picsum
。url을 통해 random으로 생성된 image를 전송.
Web App:
。Native App처럼 보이면서 기능 또한 동일하게 구현되지만, Web 기술(HTML,CSS,JS등)을 활용해서 만들어진 app.
▶ 별도의 App파일을 설치하지 않고 브라우저를 기반으로 작동.
Native App:
。Mobile 기기에 최적화된 Native 언어(kotlinorSwift)로 개발된 App
PWA (Progressive Web Apps):
。Mobile 기기에서Native App과 같은 사용자 경험을 제공하는 Web App
▶ 전통적인 Web App과 달리 Native App과 유사기능을 제공.
。Native App과Web App의 장점들만 합친것으로html,css,js등을 client side cache에 저장하여Native App처럼 사용.
。네트워크가 느린 환경 or offline 환경에서도 사용이 가능.
- 5. Convert website to PWA(Progressive Web Apps)
。기존 Web application을native app을 활용할 수 있는PWA로 변환하여 생성.
manifest.json생성 Chrome/manifest.json
。Web application의 metadata를JSON format의 text file로 제공하여 Web application을 다운로드할 수 있도록 하는 파일.
。manifest.json을 이용해PWA(Progressive Web Apps)의 설치기능을 제공하여 Web application을 데스크톱, 모바일에 설치가 가능하고 mobile application와 동일한 사용자 경험을 제공이 가능
。CRA로 react project 생성 시public폴더에 생성됨.
。Desktop에PWA생성 시512x512의 icon,Mobile에PWA생성 시192x192의 icon을 필요로 한다.{ "short_name":"Photobucket", "name" : "Photobucket Incorporation", "description" : "A PWA which enables you to share photos with friends", "icons":[{ "src":"./assets/icons/icon_512.png", "type":"image/png", "sizes":"512x512" },{ "src":"./assets/icons/icon_192.png", "type":"image/png", "sizes":"192x192" }], "screenshots" : [{ "src":"./assets/icons/screenshot.png", "type":"image/png", "sizes":"4480x2160", "form_factor":"wide" },{ "src":"./assets/icons/screenshot_mobile.jpg", "type":"image/jpg", "sizes":"542x1390", "form_factor":"narrow" }], "start_url":"../index.html", "scope" : "/", "display" : "standalone", "background_color" : "#3367D6" }
<link rel="manifest" href="./public/manifest.json">
。index.html의<head>태그 내부에manifest.json을 연결.
manifest.jsonstructure
。해당 Application의 metadata는 다음처럼 application 이름, 버전번호, 사용될icon과application에 관한 세부정보를 포함.
short_name:
。화면에 설치될icon의 이름
ex)facebook incorporation의 fullname에서
name:
。application의 이름
icons:
。application에서 사용할icon connection 배열을 정의
icon connection객체 구조
src:icon image의 주소type:icon image의 종류 ( ex."image/png")sizes:
。pixel단위 기준icon의 크기 ( ex."192x192")
。"144x144"보다는 커야한다.screenshots:
。PWA가 실행되는 desktop과 moblie 환경의 브라우저 형태를 보여주는 screenshot을 지정.
。mobile( "form_factor" : "narrow" ),desktop( "form_factor" : "wide" )를 각각 지정.
screenshot connection객체 구조
src:screenshot image의 주소type:screenshot image의 종류 ( ex."image/png")sizes:
。pixel단위 기준screenshot의 크기 ( ex."192x192")form_factor:
。wide: 좁고 세로로 긴 화면비율 ( ex. 휴대폰 )
。narrow: desktop, tablet과 같은 넓은 화면비율
start_url:
。해당 application을 실행하면 이동하는 주소
▶application의 html 주소로 연결.
display:
。application의 표시방법에 관련된 속성
display속성
fullscreen: 전체화면standalone: 상단의 URL bar 제거minimal-ui:standalone에서 일부 UI를 추가적으로 표시.browser: 일반적인 브라우저 창으로 표현 (URL bar를 표시)theme_color:
。application의 system UI 색상 지정.
scope:
。완전한 web application을 변환하지않고, 일부image,html,js등만을 이용할때 사용.
。"scope" : "/하단의주소"를 통해 범위를 설정.
。"scope" : "/"의 경우 모든 application을 변환하도록 설정.
background_color:
。application의 배경색상 지정
orientation:
。기기의 방향
orientation속성
portrait: 세로모드landscape: 가로모드
。이후, Chrome의 Web browser의 검사 페이지에서application으로 진입 시PWA관련 설정을 수행할 수 있다.
PWA관련 설정
IndexedDB
。사용자의 Browser에서 Data를 영구적으로 저장할 수 있는 DB로서 비동기적으로 작동.
。개인 화면에 오래 남아있어 저장될 데이터는IndexedDB를 활용.
。Javascript기반 객체지향DB로서Javascript가 지원하는 자료형과 객체를 저장이 가능.
。key-value형식의 복잡한 데이터를Local Storage에 비해 많게 저장 및index를 이용해 빠르게 검색할 수 있도록 설계.
▶ 보통 HDD 용량의 50%를 차지. (Local Storage의 경우 10MB)
。네트워크 상태에 상관없이 query 기능을 활용할 수 있는 Web Application을 구축할 수 있다.
▶ 해당 기능을 이용해 Web application은online mode,offline mode에서 모두 동작이 가능.
Cache storage
。특정 data, value를 미리 복사하는 임시 DB
▶CPU와 주기억장치(DRAM) 사이의 고속 임시 메모리
。Local storage의 한가지 유형으로서 네트워크에서 받아온 resource등을 저장하기위해 사용.
▶5~10MB의 용량제한이 있음.
。 자주 사용하는 data를 저장하여 요청효율을 증진하는 방식으로, 요청 시 원래 Server에서 찾아오는게 아닌, Cache로부터 data를 가져온다.Web Storage 종류
- Local Storage ex :
cache storage
。local storage의key-value형식 데이터는 사용자가 지우지 않는 이상, Browser에 영구적으로 저장하는 저장소
。브라우저에서만 사용 가능하며 서버에서 접근이 불가능하다.
。모바일은 2.5Mb,데스크탑은 5Mb~10Mb으로 저장용량을 가진다.
▶ IndexedDB를 사용하면 더 많은 용량 저장 가능
- Indexed DB
。사용자의 Browser에서 Data를 영구적으로 저장할 수 있는 DB
。key-value형식의 복잡한 데이터를Local Storage에 비해 많게 저장 및index를 이용해 빠르게 검색할 수 있도록 설계.
▶ 보통 HDD 용량의 50%를 차지. (Local Storage의 경우 10MB)
- Session Storage :
。session storage의key-valuedata는 Browser 탭을 닫는 순간 제거됨.
- Local Storage와 Session Storage의 차이점
。데이터의 영구성 :local storage의 데이터는 사용자가 지우지 않는 이상, Browser에 남아있지만session storage의 data는 Browser 탭을 닫는 순간 제거됨.
▶ 지속적으로 필요한 데이터( ex. 자동로그인 )은local storage에 저장, 일회성 정보는session storage에 저장.
- In-Memory(
Redis,H2)
。기존 디스크에서 데이터를 관리하는 DB방식과 달리, Memory(RAM)에 data를 업로드하여 사용하는 DB를 의미.
▶ 연산을 위한 Memory 영역을 대량의 데이터를 저장하여 처리할 수 있는 공간으로 활용.
Service Worker와 관련된 기능 정의하기
。PWA에서 네트워크가 불안정한 상태 또는offline상황에서도 발생할 모든 event에 대해 정의할 용도로 사용.
Service Worker:
。PWA와WebServer사이에서 가상의Proxy Server역할을 수행하면서PWA와 상호작용을 수행. 프록시서버
。느리거나 불안정한 네트워크 연결 또는 offline 환경에서 Application이 안정적으로 작동하도록하는 기능을 수행.
▶ offline 환경에서도PWA가Service Worker범위에 포함되는 Resource를 Web Server에 요청 시Service Worker가 Request를 가로챈 후Proxy Server역할을 수행.
。Service Worker는 특정 Browser(ex. chrome)의 기본적으로 설치된 Browser의 property.
▶PWA기능을 사용하려면Service Worker가 설치된 Browser를 사용.
。background script: 기본 WebPage와 별도로 작동하면서offline기능에 더하여백그라운드동기화등의 기능을 허용.
Service Worker Script생성
。기본 WebPage와 별도로 작동 Background에서 실행되는 Script.
▶navigatior.serviceWorker.register('script파일주소')를 통해 Browser에 등록하여 초기화하여 사용.
DOM요소.addEventListener('이벤트', callback 함수(evt), false)
。지정한 유형의 이벤트를 DOM요소가 수신할 때마다 호출할 함수를 설정//service_worker.js self.addEventListener('install', function(evt){ console.log("service worker is installed", evt) }) self.addEventListener('activate', function(evt){ console.log("service worker is activated", evt) }) self.addEventListener('fetch', function(evt){ console.log(evt) })
Service Worker에서 활용할 이벤트
。serviceworker객체에서 발생하는 이벤트를addEventListerner메소드를 통해 활용.
'install':
。Service Worker가 install된 경우, callback 함수 실행
'activated':
。Service Worker가 활성화된 경우 실행
'fetch':
。Service Worker가 설치 및 활성화 된 후 브라우저가 해당 Service Worker 범위 내 네트워크 요청시 실행.
。해당 Browser의 Server로 전송하는HttpRequest를 중간에 가로채고 처리할 수 있게하는 이벤트.
Service Worker초기화하는 JS파일 생성
。Browser의Service Worker를 활용하기 위해서는 우선 Browser에Service Worker Script를 등록하여Service Worker를 초기화하는 작업을 수행해야한다.
Javascript/navigator// app.js if ('serviceWorker' in navigator){ console.log('Service Worker in Browser') navigator.serviceWorker.register('./js/service_worker.js').then(()=>{ console.log('Service Worker is registered.') }).catch((err)=>{ console.log('err occured while registering ServiceWorker', err.message) }) }
Service Worker가 Browser를 지원하는 경우,Service Worker Script를 Browser에 등록하여 초기화.
。이후 해당 구문을html문서에 등록.
<script src="./js/app.js"></script>
。다음처럼 코드가 정상적으로 실행 및Chrome상의검사 - application - Service wrokers에서Service Worker Script가 정상적으로 등록됬음을 확인 가능.
。이후 상단 url 우측을 확인 시PWA의 다운로드 버튼가 생성되었음을 확인 가능.
。해당PWAApp을 설치할 경우, 다음처럼 Desktop에서 offline 환경에서도 실행가능한PWA가 생성됨을 확인 가능.
▶manifest.json,serviceworker.js,app.js의 3개 파일로 기존 Web Application을 변환하여PWA를 생성.
▶Desktop에PWA생성 시 사전에manifest.json에512x512의 icon을 정의
DefferedPrompt활용하여 Mobile Device에서prompt를 통해PWA설치여부박스 지시
Javascript/window
。manifest.json의icon에서 사전에192x192icon이 지정되어야한다.
。"beforeinstallprompt": 사용자가PWA를 Mobile Device에 설치하기 이전에prompt를 제공하기위한window객체에 발생하는 이벤트.
。prompt: 컴퓨터상에서 명령어 입력을 위한 interface.
▶event.prompt(message,defaultValue): 사용자 입력을 위한 대화상자 표시.
。아래 구문을ServiceWorker를 초기화하는 js파일(App.js)에 정의.// app.js // 사용자가 PWA를 설치하기 이전에 window객체에 발생하는 "beforeinstallprompt"를 감지하여 해당 addEventListener이 작동. var deferredPrompt; window.addEventListener("beforeinstallprompt",(evt)=>{ // 이벤트 발생 시 Browser redirection 방지 evt.preventDefault() // deferredPrompt 변수에 발생한 event 객체 지정. deferredPrompt = evt return false; })。아래 구문을
Firebase의Authentication을 정의한JS파일(Authentication.js)에 정의.// authentication.js function installalert(){ if (deferredPrompt){ // "beforeinstallprompt" event를 받아서 prompt method를 실행. deferredPrompt.prompt() // 재실행을 방지하기 위해 변수를 null로 지정. deferredPrompt = null } }。
deferredPrompt = null:PWA를 설치하기 위한 해당prompt를 한번만 실행하기 위해prompt를 실행 후 변수를null로 설정.
。이후 위installalert()method를 사용자계정이sign-in상태일 때prompt를 실행하도록auth객체.onAuthStateChanged()에서 정의.
DeferredPrompt:
。PWA에A2HS(Add to Home Screen) prompt를 추가하기 위해 사용되는 패턴.
▶ 사용자가 Device에Web App을 설치하여Native App처럼 Access할 수 있도록 하는PWA의 선택적 기능.
ngrok를 이용해PWA를 Hosting
ngrokngrok
。외부 네트워크에서 로컬 개발환경인 Web application에 접근할 수 있도록 하는 터널링 tool.
。 로컬개발환경에서 실행중인 Web Application 서버의Port를 인터넷으로 접근가능한 공용 도메인 URL로 Hosting하여 노출시키는 역할을 수행.
▶ 이를 활용해 로컬개발환경의 Web application을 Hosting하여 publish가 가능한지 판단하는 용도로 사용함.
ngrok에서 회원가입 후ngrok token발급
。token:Client-side에서 인증정보를 보관하는 방법.
。ngrok에서Your Authtoken을 통해 token을 확인 가능.
ngrok.exe터미널 실행 후ngrok명령어 입력
。토큰설정 :ngrok config add-authtoken 토큰
▶ Hosting을 위해 먼저Token을 등록.
。로컬서버에 도메인 연결하기 :ngrok http 로컬포트번호
▶ 로컬포트번호(5500)로 실행중인 Web application을 외부 네트워크로 노출시키기 위한 명령을 수행.
。 로컬포트번호(5500)와 연결된 도메인 주소를 지시.
▶ 해당 도메인 주소를 입력 시 외부 네트워크를 통해 Web application에 접근가능.
▶ 모바일 환경으로 접근한 경우.
Fetch API
。Client와 Server간 상호작용을 위한HTTP Pipeline을 구성하는 request와 response를Javascript에서 접근하여 조작할 수 있는 Interface.
。Page 전체를 reload하지 않고도Http Request를 수행할 수 있다.
▶XMLHttpRequest와 유사.
。GET,POST등의 모든HTTP Request method를 지원.
。Callback기반인XMLHttpRequest와 다르게 Promise 기반 비동기 통신을 지원.
Firebase DataBase
- Realtime Database
。실시간 데이터동기화 기능을 제공하는NoSQL JSON DB
。 여러 client에서 실시간으로 상태를 동기화를 수행하기위해 효율적이고 지연시간이 짧음.
。Data를 하나의 대형JSON tree구조를 가진 객체로 저장되며,key-value쌍으로 구성.
▶ 단순한 데이터를 쉽게 저장하지만, 복잡한 계층적 데이터를 대규모로 정리하기 어렵다.
。 간단한 조회 및 확장성이 제한적이며 지연시간이 짧은 단순한 데이터모델을 사용하는 Application에 적합
- Cloud Firestore
。데이터를Document,Collection으로 저장하는NoSQL DB로서Realtime DB를 바탕으로 생성.
。Cloud Firestore의 Data Model은 유연한 계층적 데이터 구조를 지원
。고급 쿼리문, 확장성을 가진 데이터모델을 사용하는 Application에 적합.
단순한JSON tree구조의 data로 구성된 다수의 구조화된 DB를 가질 때Realtime DB를,Collection으로 구성된 대용량데이터를 자주 활용하며 단일 DB를 가질 때 Cloud Firestore를 사용Firebase DB 특징
- 비관계형
Cloud NoSQL DB
。Document( RDBMS의record) :JSON format의 Data를 저장하고, 중첩된 구조를 가질 수 있다.
。Collection( RDBMS의table) :Document를 포함하고, Data를 저장하는 역할을 수행.
- 실시간이 가능
。데이터가 필요할 때마다 서버 DB에 요청하여 접근하는것이 아닌, 동기화 방식을 사용.
- 오프라인 상태에서도 Data를 유지가능
。오프라인상태의 경우 Data를 Local 환경의 Web Application에 저장하다가 네트워크 연결 시 Local에 저장된 데이터를 동기화.
- 서버 없이 Web Application만으로 동작이 가능
。Web application에서Firebase Realtime DB에 접근이 가능하므로 별도의 서버 없이 동작이 가능.
- 6. POST data
。Fetch API,Firebase Realtime Database활용.
Firebase에서 Realtime Database 생성하기.
。테스트 모드로 생성
▶ Realtime Database이므로,JSON tree구조의 데이터로 저장.
。Realtime DB구축 후 Web Application에 적용할Data를 작성.
▶ 다음 형식(JSON)의 data를DB에 정의.
- Web application 상에 이미지 데이터를 첨부하는 기능 구현
Map상에 데이터를 추가할 버튼UI생성<!-- Logged --> <div id="logged" style="display:none"> <div id="map"></div> <button class="btn btn-success" type="submit" style="border-radius:50%; position:absolute; right:10px; bottom:40px" data-bs-toggle="modal" data-bs-target="#addModal"> <i class="fa-solid fa-house"></i> </button> </div>。
<button>에data-bs-toggle="modal" data-bs-target="#addModal"를 지정.
▶data-toggle="modal"는 작동하지 않는다.
。 우측 하단에 버튼이 생성됨을 확인 가능.
▶icon은 font awesome에서 가져옴.
bootstrap의modal을 활용하여 사진을 첨부하는 기능 정의.
。modal의<body>에 파일을 첨부하는<input type="file">과 이미지파일 첨부 시 해당 이미지를 미리보기로 제공하기위해<canvas>를 추가.<!-- Modal --> <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="addModalLabel">사진 첨부하기</h5> </button> </div> <div class="modal-body"> <label for="addtext1">Edit about Photo</label> <input type="text" id="addtext1" name="addtext1"> <hr> <input type="file" name="addfile1" accept="image/*" onchange="addingtoCanvas(this)" capture> <hr> <canvas id="capturedImg" width="240px" height="320px"></canvas> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-primary" onclick="getLocation()">Submit</button> </div> </div> </div>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
。data-bs-dismiss="modal"로 설정 시 Close 기능이 활성화됨.<div class="modal-body"> <label for="addtext1">Edit about Photo</label> <input type="text" id="addtext1" name="addtext1"> <hr> <input type="file" name="addfile1" accept="image/*" onchange="addingtoCanvas(this)" capture> <hr> <canvas id="capturedImg" width="240px" height="320px"></canvas> </div>。
<input>: 입력값 변화 시this를 통해 입력된 데이터(File)가js의callback함수로 전달 후 실행.
。Modal은 해당 디자인으로 설정되었으며 이미지 첨부 시 다음 canvas로 이미지가 표현됨.
- 이미지 첨부 기능 관련 함수 구현하기
。이미지 첨부 시 HTML의modal에서 정의한<canvas>에서 첨부한 이미지를 미리보기로 제공.// func.js var canvas = document.getElementById('capturedImg') // input을 통해 입력력된 value를 매개변수로 받는다 function addingtoCanvas(file){ var render = new FileReader() // Image File의 load가 완료된 경우 onload 이벤트를 통해 첨부할 Image를 html <canvas>에 표현. render.onload = ( evt )=>{ // 이미지 객체 생성 var img = new Image() // File load가 완료되었을때의 data를 첨부된 image file의 source를 지정. img.src = evt.target.result // image의 Load가 완료될 경우 onload 이벤트 호출. img.onload = ()=>{ // html <canvas>에 표현할 2D Context 객체 생성 및 img 객체에 Load된 Image를 canvas에 표현 var ctx = canvas.getContext('2d') ctx.drawImage(img,0,0,240,320) } } // html <input type="file">을 통해 첨부된 파일을 Resource URL로 return하여 반환. return render.readAsDataURL(file.files[0]) }관련 기능
event객체.target.result: File에서 Read된 data를 image 객체의 result로 지정.
▶ 아래사진처럼 File에 첨부된 이미지를Base64로 encoding된Resource URL로 반환하여img객체의src로 지정하여img객체의 이미지 설정.
。이후img객체에 image가 load된 경우onload이벤트가 발생하여<canvas>element 변수에img객체를 추가.
▶ 모바일에서는 다음처럼 촬영한 사진을 첨부할 수 있음.
Modal을 통해 사진 첨부시 해당 위치를 획득하는 기능 생성하기
。Modal의 버튼을 누르는 순간의 위치정보를 획득.
。navigator.geolocation객체 이용 navigator.geolocation 객체
。Modal의<button>의onclick=""을 통해POST기능을 구현한 함수를 설정.<button type="button" class="btn btn-primary" onclick="getLocation()">Submit</button>。
Modal의<div class="modal-body">내부에 현재 기기의 위경도 좌표를 지시하는<div>생성<div id="position_info" style="padding:10px"></div>。사용자 위치정보 획득 및 지시하는 함수 구현하기.
// func.js var userLocation var Recall = true // 재요청 여부 function getLocation(){ // 위경도 좌표 정보 요청 navigator.geolocation.getCurrentPosition(showLocation,failLocation) // Success Callback : 매개변수 position을 통해 위 경도 정보 제공 및 데이터 전송. function showLocation(position){ var lat = position.coords.latitude var long = position.coords.longitude // modal창 body 내부에 현재 위경도 정보 지시 document.getElementById('position_info').innerHTML="<p>"+"current position : "+lat+" , "+long+"</p>" document.getElementById('position_info').style.color = "green" // 전송할 위,경도 데이터를 JSON Format으로 생성. userLocation = { longitude : long, latitude : lat } // 위치정보가 성공적으로 획득 시 Recall 변수를 false로 설정하여 재획득하지 않도록함. Recall = false } // Error Callback : 매개변수 error function failLocation(err){ document.getElementById('position_info').innerHTML="<p>"+err.message+" : Turn On your GPS"+"</p>" document.getElementById('position_info').style.color = "red" userLocation = undefined if (Recall){ // 위치정보 획득 실패 시 재요청. navigator.geolocation.getCurrentPosition(showLocation,failLocation) } } }。
navigator.geolocation.getCurrentPosition(Success Callback, Error Callback, option): 현재 User Device의 위치를 검색.
- 특정 이메일 계정에 첨부한 데이터를 보내는 기능 생성하기.
。Firebase의Authentication에서onAuthStateChanged(auth객체,callback)에서 callback함수 매개변수user의user.email을 통해 현재 로그인한 계정의 정보 획득.
Firebase의Storage기능 활용
Firebase Storage: 이미지, 동영상과 같은 Contents를 저장할 수 있는 저장소.
▶Firebase DB는 해당 미디어 콘텐츠를 저장하는 기능이 없으므로,Firebase Storage사용.
이후는 Firebase가 유료이므로, 현재는 보류.