현재 위치 - 인적 자원 플랫폼망 - APP 개발 - Javascript "동기화" 호출 app 코드를 구현하는 방법
Javascript "동기화" 호출 app 코드를 구현하는 방법
App 의 혼합 개발에서 App 계층이 js 계층에 인터페이스를 제공하는 두 가지 방법이 있습니다. 하나는 동기 인터페이스이고 다른 하나는 비동기 인터페이스입니다 (여기서 토론을 볼 수 있는 동기화가 무엇인지 알 수 없음). 웹의 유창함을 보장하기 위해 비동기 인터페이스를 사용해야 하는 경우가 많지만 경우에 따라 동기식 인터페이스가 더 필요할 수도 있습니다. 동기화 인터페이스의 장점은 첫째, js 가 반환 값을 통해 실행 결과를 얻을 수 있다는 것입니다. 둘째, 혼합 개발에서 app 레이어에서 내보낸 일부 API 는 의미에 따라 동기화되어야 합니다. 그렇지 않으면 이상할 수 있습니다. 하나는 for 루프에 사용될 수 있으며, 구성 항목을 읽고 쓰는 것과 같이 속도가 빠른 인터페이스를 실행하는 것이 이상할 수 있습니다.

그렇다면 동기화 인터페이스를 js 레이어로 내보내는 방법은 무엇입니까?

Android 프레임워크에서 Java 인터페이스는 함수 WebView.addJavascriptInterface () 를 통해 js 레이어로 내보낼 수 있으므로 내보낸 인터페이스가 동기화 인터페이스입니다. 그러나 iOS 의 COA 프레임워크에서는 동기화 인터페이스를 내보내는 것이 쉽지 않습니다. UIWebView 와 WKWebView 에는 addJavascriptInterface 기능이 없기 때문입니다. 동시에 Android 의 기능에도 보안 취약점이 생겼다. 그럼, 동기화 호출을 할 수 있는 다른 방법이 있나요? IOS UIWebView 를 예로 들자면, WKWebView 와 Android 도 참고할 수 있습니다.

문제의 핵심을 찾기 위해 iOS 에서 js 호출 app 를 구현하는 일반적인 방법을 살펴보겠습니다.

먼저 UIWebViewDelegate 를 사용자 정의하고 shouldstartloadwithrequest: navigationtype 함수에서 다음을 수행합니다.

1

2

셋;삼;3

다섯;오;5

여섯;육

일곱

여덟;팔

아홉;구;9

10

1 1

12

13

14

15

16

-(bool) webview: (ui webview * _ nonnull) webview

Shouldstartloadwithrequest: (nsurlrequest * _ nonnull) 요청

Navigationtype: (uiwebviewnavigationtype) navigationtype {

만약 ([요청]. Http method compare: @ "get" options: nscaseinsensitivesearch]! = NSOrderedSame) {

//비 get 요청을 처리하지 않습니다.

YES 를 반환합니다

}

NSURL* URL = 요청. 웹 사이트

If ([url.scheme is equal tostring: @' yourcustomprotocol']) {

Return [self on my request: request];

}

YES 를 반환합니다

}

이 메서드는 기본적으로 함수 호출 명령을 URL 로 변환하여 요청 시 app 계층에 알리는 것입니다. 여기서 onMyRequest: 는 사용자 정의 요청 응답 함수입니다. 요청을 보내기 위해 js 계층은 숨겨진 iframe 요소를 만들고 요청을 보낼 때마다 iframe 요소의 src 속성을 수정하여 app 가 해당 요청을 차단할 수 있도록 합니다.

1

2

셋;삼;3

다섯;오;5

여섯;육

일곱

여덟;팔

아홉;구;9

10

1 1

12

13

/* *

* js 는 네이티브에 메시지를 전달합니다.

* @ methodjs _ sendmessagetonativasync

* @ member of jstonativeiospolyfill

* @public

* @param str {String} 메시지 문자열, HybridMessage 에서 변환됨.

*/

Jstonativeiospolyfill.prototype.js _ sendmessagetonativeasync = function (str) {

만약 (! This.ifr_) {

이것. _ prepareifr ();

}

This.ifr_. Src =' yourcustomprotocol://_ _ _ message _ send _ _? Msg = '+encodeURIComponent(str); (str); }

App 가 js 호출의 함수를 실행할 때 실행 결과를 직접 반환할 수 없습니다. 결과를 반환하기 위해 일반적으로 콜백 함수인 ——JS 레이어를 사용하여 콜백을 기록합니다. app 는 jsonp 와 유사한 메커니즘인 UIWebView 의 Stringbyevaluationjavascriptfromstring 함수를 통해 이 콜백을 호출합니다.

이런 방식으로 캡슐화된 인터페이스는 당연히 비동기적입니다. 함수 js _ sendMessageToNativeAsync 는 실행 결과가 반환될 때까지 기다리지 않고 즉시 반환하기 때문입니다.

따라서 js 코드를 "차폐" 하는 방법을 찾아야합니다.

Js 에서 어떤 방법으로 CPU 를 가득 채우지 않고 UI 스레드 코드를 "차단" 할 수 있는지 생각해 보십시오.

1

2

셋;삼;3

Var async = false

Var URL = \ "\";

Var 메서드 =' get & ltbr & gt var req = new xmlhttprequest (); & ltbr & gt

Req.open (메소드, URL, 비동기); & ltbr & gtreq.send (비어 있음);

"동기" Ajax (사실 이 단어가 없고, Ajax 는 비동기를 의미함) 네! 이 코드는 바이두의 응답이 반환될 때까지 계속 차단될 것이다. 일반적으로 동기화 요청은 허용되지 않으며 이로 인해 UI 카튼의 위험이 발생할 수 있습니다. 하지만 여기서, 우리가 실제로 원격으로 내용을 요청하지 않기 때문에, 우리는 그것을 사용할 수 있습니다.

지금까지 구현 방법이 비교적 명확해졌으니, 이제 생각을 정리해 보겠습니다.

XMLHttpRequest 와 특별히 구성된 URL 을 동기화하여 응용 프로그램 계층에 알립니다.

애플리케이션 계층은 함수 실행 요청을 가로채고 결과를 응답으로 반환합니다.

XMLHttpRequest.send () 는 status 및 responseText 를 통해 결과를 반환합니다.

그럼 어떻게 요청을 가로막을까요? UIWebViewDelegate 는 XMLHttpRequest 요청을 가로채지 않는 것으로 알려져 있지만, iOS 는 최소한 ——Nsurlcache 와 NSURLProtocol 의 두 가지 요청을 가로막는 장소를 제공합니다.

1.NSURLCache 는 iOS 에서 사용자 정의 캐시를 구현하는 클래스입니다. 사용자 정의 NSURLCache 하위 클래스 객체를 만들어 글로벌 캐시 관리자로 설정하면 모든 요청이 먼저 여기에 도착하여 캐시를 금지하지 않는 경우 캐시가 있는지 확인합니다. 이 속성을 사용하여 인터페이스 호출 요청을 가로채고 데이터를 실행 및 반환할 수 있습니다.

1

2

셋;삼;3

다섯;오;5

여섯;육

일곱

여덟;팔

아홉;구;9

10

1 1

12

13

14

15

16

17

18

19

20

2 1

22

23

24

25

26

-(nscachedurlresponse *) cachedresponseforrequest: (nsurlrequest *) request {

만약 ([요청]. Http method compare: @ "get" options: nscaseinsensitivesearch]! = NSOrderedSame) {

//get 요청만 사용자 정의합니다.

Return [supercachedresponseforrequest: request];

}

NSURL* URL = 요청. 웹 사이트

NSString * path = url.path

NSString * query = url.query

If (path == nil || query == nil) {

Return [supercachedresponseforrequest: request];

}

LOGF(@"url = %@, 경로 =% @, 쿼리 =% @ ",URL, 경로, 쿼리);

If ([경로 is equal tostring: @ "_ _ env _ get _ _"]) {

//환경 변수 읽기

Return [self getenvvaluebyurl: URL]; //*

} elseif ([path is equal tostring: @ "_ _ env _ set _ _"]) {

//쓰기 환경 변수

Return [self setenvvaluebyurl: URL];

}

Return [supercachedresponseforrequest: request];

}

주의 * 줄은 app 인터페이스를 실행하여 결과를 반환하는 것입니다. 여기 결과는 NSCachedResponse 대상이기 때문에 군더더기는 하지 않겠습니다.