PWA를 기본 iOS/Android 애플리케이션에 내장하는 방법
23303 단어 androidiospwajavascript
PWA는 Nuxt로 구축되기 때문에 예시 코드는 Nuxt가 특정하지만 원칙은 각 PWA에 적용된다.
카탈로그📖
왜?🤔
잘 물었습니다.당신은 다음과 같은 몇 가지를 고려할 수 있습니다.
스토리지 및 로그인 세션🍪
PWA가 WKWebView(>=iOS 8)에 표시됩니다.이 프로그램의 iframe로 볼 수 있습니다.모든 WKWebView는 자신의 저장 데이터(Cookie, local Storage, IndexedDB 등)를 가지고 있으며, 이 데이터는 닫히고 다시 열면 복구됩니다.그러나 네이티브 애플리케이션은 WebView와 자체 쿠키를 공유하지 않습니다.
따라서 사용자가 로그인해야 할 경우 WebView에서 PWA를 연 후 다시 로그인하지 않도록 로그인 세션을 수동으로 재사용해야 합니다.
이를 위해 프로그램 개발자는 초기 프로그램 로그인 화면이나 지문에서 얻은 세션/영패 설정 쿠키를 사용할 수 있다.WebView에 쿠키를 설정하려면 다음을 사용할 수 있습니다WKHTTPCookieStore.
커뮤니케이션📨
PWA와 네이티브 애플리케이션이 서로 대화하고 작업을 수행하도록 알리기를 원할 수도 있습니다.그래서 우리는 다리를 건설해야 한다. 그곳에서 그들은 서로 이야기를 나눌 수 있다.
이를 위해, 우리는 두 가지 방법으로 전역 대상 (window.bridge
을 추가할 것이다.하나는 PWA 내부에서 본체 응용 프로그램의 조작을 호출하는 데 사용되고, 다른 하나는 메시지와 명령을 수신하는 데 사용되며, 이 메시지와 명령은 본체 응용 프로그램에서 실행될 것이다.이 방법에서 우리는 정보를 Vuex 저장소에 넣어서 그것들을 관찰할 수 있다.
방법 이름, iOS/Android 개발자에게 전달되는 데이터 구조, 수신된 데이터는 사용자와 응용 프로그램 개발자에 달려 있습니다.
응용 개발자는 JS 코드를 WebView에 주입할 수 있습니다.우리의 예에서, 그는 JSON 문자열을 수신하는 전역 방법 invokeNative
을 정의해야 한다.우리는 이 기능을 검사해서 우리가 응용 프로그램에 있는지 일반 브라우저에 있는지 검사할 수 있다.
다음은 Nuxt 플러그인에 포함된 브리지 코드입니다.
// bridge.client.js nuxt plugin
export default (context, inject) => {
// force app mode with ?app param to be able to test
const { app } = context.query;
// determine whether the app is opened inside native app
const inApp = !!window.invokeCSharpAction
|| typeof app !== 'undefined';
// inject global $inApp variable and
inject('inApp', inApp);
context.store.commit('setInApp', inApp);
// the bridge object in the global namespace
window.bridge = {
// invoke native function via PWA
invokeNative(data) {
if (!window.invokeCSharpAction) {
return;
}
window.invokeCSharpAction(
JSON.stringify(data)
);
},
// called by native app
invokedByNative(data) {
// write passed data to the store
context.store.commit(
'addAppMessage',
JSON.parse(data)
);
}
}
inject('bridge', window.bridge);
}
브리지를 설치한 후에는 다음과 같이 PWA에서 네이티브 작업을 호출할 수 있습니다.
// callable in stores, components & plugins
this.$bridge.invokeNative({
function: 'Close'|'SaveSomething'
payload: {
lang, title, ...
}
});
네이티브 애플리케이션 개발자는 다음 JS 코드를 실행하여 PWA 작업을 호출할 수 있습니다.
// callable in native app
this.$bridge.invokedByNative({
function: 'GoBack'|'HasSavedSomething'
response: {
success, ...
}
});
Vuex 스토리지의 저장 작업은 다음과 같습니다.
async saveSomething({ state, commit, rootGetters }) {
// prevent saving while it's already saving
if (state.isSaving) {
return;
}
commit('setIsSaving', true);
// data we want to pass to the app or to our API
const payload = { ... };
// call the bridge method inside app
if (this.$inApp) {
this.$bridge.invokeNative({
function: 'SaveSomething',
payload
});
// otherwise we will call the API like we're used to
} else {
// await POST or PUT request response ...
// finish saving and set response id
if (response.success) {
commit('setId', response.id);
} else {
// Failed, inform user 😢
}
commit('setIsSaving', false);
}
}
일반 API 호출에서 얻은 것처럼 브리지 연결 방법에서 직접적인 응답을 받지 못할 수도 있습니다.응용 프로그램이 언제 실행되었는지, 성공했는지 알 수 있도록, 본 프로그램의 호출 invokedByNative
방법을 통해 우리에게 통지해야 합니다.PWA에서는 다음과 같은 메시지를 들을 수 있습니다.
// inside app / layout component
import { mapState, mapMutations } from 'vuex';
export default {
computed: {
// map messages and isSaving to show a loader e.g.
...mapState(['appMessages', 'isSaving'])
},
methods: {
// map necessary mutations
...mapMutations(['setId', 'setIsSaving'])
},
watch: {
// watch the messages from the store for any changes
appMessages(mgs) {
// get last received message
const lastMsg = mgs[mgs.length - 1];
const appFunction = lastMsg.function;
const response = lastMsg.response || {};
// check if last message belongs to function we expect a response from
if (appFunction === 'HasSavedSomething') {
if (response.success) {
this.setId(response.id);
} else {
// Failed, inform user 😢
}
this.setIsSaving(false);
}
}
}
};
지금 우리는 이미 다리를 놓아서 서로 명령을 발송할 수 있다.
항행🧭
PWA가 기본 응용 프로그램의 일부로서 WebView에서 실행되는 경우 전체 응용 프로그램을 닫지 않고도 항상 응용 프로그램으로 돌아갈 수 있는지 확인합니다.
이전에 Nuxt 플러그인에 설정한 전역 window.invokeCSharpAction
변수를 사용하여 템플릿과 구성 요소를 변경할 수 있습니다.WebView에서 PWA를 열면 메뉴 표시줄에 닫기 버튼을 표시하거나 다른 설계를 조정할 수 있습니다.
또한 응용 프로그램 개발자는 404나 500 등 HTTP 오류를 포획하고 WebView를 닫으며 사용자에게 알림 메시지를 표시할 수 있도록 해야 한다.
또 다른 도전은 후퇴 버튼/내비게이션을 실현하는 것이다.Android에서는 일반적으로 아래쪽에 후퇴 버튼이 있습니다.iOS에는 없지만 슬라이딩 제스처를 사용할 수 있습니다.
사용자가 돌아올 때 이전에 방문한 사이트가 있으면 PWA 내부에서 호출해야 한다. 그렇지 않으면 WebView를 닫아야 한다.
불행하게도, invokedByNative
API는 현재 기록 항목의 위치를 감지하거나 접근할 수 없습니다.또한 $inApp
가 PWA에서 URL 업데이트에 사용될 때canGoBack 속성도 작동하지 않는 것 같습니다.
PWA 내부에서 당사의 내역/역추적 목록을 구현하여 이 문제를 해결할 수 있습니다.
// inside app / layout component
export default {
data() {
return {
history: []
}
},
watch: {
// watch route which updates when URL has changed
'$route'(to, from) {
// find if target page has been visited
const entry = this.appRouteHistory
.findIndex(
entry => to.path === entry.from.path
);
if (entry > -1) {
// back navigation:
// remove every entry that is
// after target page in history
this.appRouteHistory.splice(entry);
} else {
// forward navigation
this.appRouteHistory.push({ to, from });
}
}
},
methods: {
goBack() {
const lastAppHistoryEntry = this.appRouteHistory.length > 0
? this.appRouteHistory[this.appRouteHistory.length-1]
: null;
if (lastAppHistoryEntry) {
// go back to last entry
this.$router.push(lastAppHistoryEntry.from);
} else {
// tell the app it should close the WebView
this.$bridge.invokeNative({
function: 'Close'
})
}
}
}
}
개발자는 응용 프로그램 내에서 후퇴 버튼 기능을 덮어쓰고 다음 JS 코드를 호출할 수 있습니다.
// callable in native app to go back in PWA or close WebView
this.$bridge.invokedByNative({ function: 'GoBack' });
마지막으로 감청history.back
방법 중의 window.history
메시지(상기 통신 부분의 실현 참조)를 확보하고 pushState
방법을 호출해야 한다.
if (appFunction === 'GoBack') {
this.goBack();
}
결말🔚
나는 이 글이 너로 하여금 PWA와 (기존) 원본 응용 프로그램 사이의 연결을 어떻게 하는지 신속하게 이해하게 할 수 있기를 바란다.만약 당신에게 어떤 문제가 있다면, 메시지를 남겨 주세요.
Reference
이 문제에 관하여(PWA를 기본 iOS/Android 애플리케이션에 내장하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/oncode/how-to-embed-a-pwa-into-a-existing-native-ios-android-app-2p4l
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
PWA와 네이티브 애플리케이션이 서로 대화하고 작업을 수행하도록 알리기를 원할 수도 있습니다.그래서 우리는 다리를 건설해야 한다. 그곳에서 그들은 서로 이야기를 나눌 수 있다.
이를 위해, 우리는 두 가지 방법으로 전역 대상 (
window.bridge
을 추가할 것이다.하나는 PWA 내부에서 본체 응용 프로그램의 조작을 호출하는 데 사용되고, 다른 하나는 메시지와 명령을 수신하는 데 사용되며, 이 메시지와 명령은 본체 응용 프로그램에서 실행될 것이다.이 방법에서 우리는 정보를 Vuex 저장소에 넣어서 그것들을 관찰할 수 있다.방법 이름, iOS/Android 개발자에게 전달되는 데이터 구조, 수신된 데이터는 사용자와 응용 프로그램 개발자에 달려 있습니다.
응용 개발자는 JS 코드를 WebView에 주입할 수 있습니다.우리의 예에서, 그는 JSON 문자열을 수신하는 전역 방법
invokeNative
을 정의해야 한다.우리는 이 기능을 검사해서 우리가 응용 프로그램에 있는지 일반 브라우저에 있는지 검사할 수 있다.다음은 Nuxt 플러그인에 포함된 브리지 코드입니다.
// bridge.client.js nuxt plugin
export default (context, inject) => {
// force app mode with ?app param to be able to test
const { app } = context.query;
// determine whether the app is opened inside native app
const inApp = !!window.invokeCSharpAction
|| typeof app !== 'undefined';
// inject global $inApp variable and
inject('inApp', inApp);
context.store.commit('setInApp', inApp);
// the bridge object in the global namespace
window.bridge = {
// invoke native function via PWA
invokeNative(data) {
if (!window.invokeCSharpAction) {
return;
}
window.invokeCSharpAction(
JSON.stringify(data)
);
},
// called by native app
invokedByNative(data) {
// write passed data to the store
context.store.commit(
'addAppMessage',
JSON.parse(data)
);
}
}
inject('bridge', window.bridge);
}
브리지를 설치한 후에는 다음과 같이 PWA에서 네이티브 작업을 호출할 수 있습니다.// callable in stores, components & plugins
this.$bridge.invokeNative({
function: 'Close'|'SaveSomething'
payload: {
lang, title, ...
}
});
네이티브 애플리케이션 개발자는 다음 JS 코드를 실행하여 PWA 작업을 호출할 수 있습니다.// callable in native app
this.$bridge.invokedByNative({
function: 'GoBack'|'HasSavedSomething'
response: {
success, ...
}
});
Vuex 스토리지의 저장 작업은 다음과 같습니다.async saveSomething({ state, commit, rootGetters }) {
// prevent saving while it's already saving
if (state.isSaving) {
return;
}
commit('setIsSaving', true);
// data we want to pass to the app or to our API
const payload = { ... };
// call the bridge method inside app
if (this.$inApp) {
this.$bridge.invokeNative({
function: 'SaveSomething',
payload
});
// otherwise we will call the API like we're used to
} else {
// await POST or PUT request response ...
// finish saving and set response id
if (response.success) {
commit('setId', response.id);
} else {
// Failed, inform user 😢
}
commit('setIsSaving', false);
}
}
일반 API 호출에서 얻은 것처럼 브리지 연결 방법에서 직접적인 응답을 받지 못할 수도 있습니다.응용 프로그램이 언제 실행되었는지, 성공했는지 알 수 있도록, 본 프로그램의 호출 invokedByNative
방법을 통해 우리에게 통지해야 합니다.PWA에서는 다음과 같은 메시지를 들을 수 있습니다.// inside app / layout component
import { mapState, mapMutations } from 'vuex';
export default {
computed: {
// map messages and isSaving to show a loader e.g.
...mapState(['appMessages', 'isSaving'])
},
methods: {
// map necessary mutations
...mapMutations(['setId', 'setIsSaving'])
},
watch: {
// watch the messages from the store for any changes
appMessages(mgs) {
// get last received message
const lastMsg = mgs[mgs.length - 1];
const appFunction = lastMsg.function;
const response = lastMsg.response || {};
// check if last message belongs to function we expect a response from
if (appFunction === 'HasSavedSomething') {
if (response.success) {
this.setId(response.id);
} else {
// Failed, inform user 😢
}
this.setIsSaving(false);
}
}
}
};
지금 우리는 이미 다리를 놓아서 서로 명령을 발송할 수 있다.항행🧭
PWA가 기본 응용 프로그램의 일부로서 WebView에서 실행되는 경우 전체 응용 프로그램을 닫지 않고도 항상 응용 프로그램으로 돌아갈 수 있는지 확인합니다.
이전에 Nuxt 플러그인에 설정한 전역 window.invokeCSharpAction
변수를 사용하여 템플릿과 구성 요소를 변경할 수 있습니다.WebView에서 PWA를 열면 메뉴 표시줄에 닫기 버튼을 표시하거나 다른 설계를 조정할 수 있습니다.
또한 응용 프로그램 개발자는 404나 500 등 HTTP 오류를 포획하고 WebView를 닫으며 사용자에게 알림 메시지를 표시할 수 있도록 해야 한다.
또 다른 도전은 후퇴 버튼/내비게이션을 실현하는 것이다.Android에서는 일반적으로 아래쪽에 후퇴 버튼이 있습니다.iOS에는 없지만 슬라이딩 제스처를 사용할 수 있습니다.
사용자가 돌아올 때 이전에 방문한 사이트가 있으면 PWA 내부에서 호출해야 한다. 그렇지 않으면 WebView를 닫아야 한다.
불행하게도, invokedByNative
API는 현재 기록 항목의 위치를 감지하거나 접근할 수 없습니다.또한 $inApp
가 PWA에서 URL 업데이트에 사용될 때canGoBack 속성도 작동하지 않는 것 같습니다.
PWA 내부에서 당사의 내역/역추적 목록을 구현하여 이 문제를 해결할 수 있습니다.
// inside app / layout component
export default {
data() {
return {
history: []
}
},
watch: {
// watch route which updates when URL has changed
'$route'(to, from) {
// find if target page has been visited
const entry = this.appRouteHistory
.findIndex(
entry => to.path === entry.from.path
);
if (entry > -1) {
// back navigation:
// remove every entry that is
// after target page in history
this.appRouteHistory.splice(entry);
} else {
// forward navigation
this.appRouteHistory.push({ to, from });
}
}
},
methods: {
goBack() {
const lastAppHistoryEntry = this.appRouteHistory.length > 0
? this.appRouteHistory[this.appRouteHistory.length-1]
: null;
if (lastAppHistoryEntry) {
// go back to last entry
this.$router.push(lastAppHistoryEntry.from);
} else {
// tell the app it should close the WebView
this.$bridge.invokeNative({
function: 'Close'
})
}
}
}
}
개발자는 응용 프로그램 내에서 후퇴 버튼 기능을 덮어쓰고 다음 JS 코드를 호출할 수 있습니다.
// callable in native app to go back in PWA or close WebView
this.$bridge.invokedByNative({ function: 'GoBack' });
마지막으로 감청history.back
방법 중의 window.history
메시지(상기 통신 부분의 실현 참조)를 확보하고 pushState
방법을 호출해야 한다.
if (appFunction === 'GoBack') {
this.goBack();
}
결말🔚
나는 이 글이 너로 하여금 PWA와 (기존) 원본 응용 프로그램 사이의 연결을 어떻게 하는지 신속하게 이해하게 할 수 있기를 바란다.만약 당신에게 어떤 문제가 있다면, 메시지를 남겨 주세요.
Reference
이 문제에 관하여(PWA를 기본 iOS/Android 애플리케이션에 내장하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/oncode/how-to-embed-a-pwa-into-a-existing-native-ios-android-app-2p4l
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
// inside app / layout component
export default {
data() {
return {
history: []
}
},
watch: {
// watch route which updates when URL has changed
'$route'(to, from) {
// find if target page has been visited
const entry = this.appRouteHistory
.findIndex(
entry => to.path === entry.from.path
);
if (entry > -1) {
// back navigation:
// remove every entry that is
// after target page in history
this.appRouteHistory.splice(entry);
} else {
// forward navigation
this.appRouteHistory.push({ to, from });
}
}
},
methods: {
goBack() {
const lastAppHistoryEntry = this.appRouteHistory.length > 0
? this.appRouteHistory[this.appRouteHistory.length-1]
: null;
if (lastAppHistoryEntry) {
// go back to last entry
this.$router.push(lastAppHistoryEntry.from);
} else {
// tell the app it should close the WebView
this.$bridge.invokeNative({
function: 'Close'
})
}
}
}
}
// callable in native app to go back in PWA or close WebView
this.$bridge.invokedByNative({ function: 'GoBack' });
if (appFunction === 'GoBack') {
this.goBack();
}
나는 이 글이 너로 하여금 PWA와 (기존) 원본 응용 프로그램 사이의 연결을 어떻게 하는지 신속하게 이해하게 할 수 있기를 바란다.만약 당신에게 어떤 문제가 있다면, 메시지를 남겨 주세요.
Reference
이 문제에 관하여(PWA를 기본 iOS/Android 애플리케이션에 내장하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/oncode/how-to-embed-a-pwa-into-a-existing-native-ios-android-app-2p4l텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)