iyOmSd/Title: Swift

[Swift] - JavaScriptCore(1/2)

냄수 2020. 5. 16. 01:39
반응형

이번 게시글은

JavaScript 언어를 iOS에 맞게 맵핑 해보는 기능에 대해서

공부를 하면서 적어봤어요

 

 

Apple에서 기본적으로 제공되는 Framework 에요

WKWebView에서 JavaScript를 이용한 맵핑기능이 몇가지 제공되는게 있어요

 

이미있는 API가 아니라 Core를 공부하는 거니까

JavaScript에 맞게 코드가 작동되도록 구현해볼거에요

 

 

사용하기에 앞서 알아야할 개념을 볼게요

 

JSVirtualMachine

JS코드가 여기서 실행되고

JSVirtualMachine하나로 여러 스레드를 동시 실행할 수 없고

병렬처리를 하기위해서는 여러 가상머신을 사용해야한다고 해요

따라서 이것을 새로 생성하라는거죠

 

두 가지 주요 목적

JavaScript 동시 실행을 지원하는 것과 JavaScript와 Object C

또는 Swift 간에 브리지된 개체의 메모리를 관리

 

 

 

JSContext

 

자바스크립트코드의 실행환경
단일 전역 객체
동일가상머신에 있는경우 컨텍스트간 객체를 자유롭게 전달가능

JavaScript에서 기본 객체, 방법 또는 함수 액세스가능

 

 

 

JSValue

작업해야할 기본데이터유형
가능한 모든 자바스크립트값 나타낼수있음
JSValue에 존재하는 JSContext객체에 연결

 

네이티브 코드와 자바 스크립트 간의 데이터를 전달

자바 스크립트와 오브젝티브-C나 스위프트 표현 사이에

(숫자와 문자열과 같은)기본 값을 변환하는 데는 JSValue 클래스를 사용

 

 

아래는 자료를 찾아보다가 이해하기 좋은 이미지인거 같아서

레이웬더위치에서 가져왔어요

 

 

JavaScript Code를 사용하는 방법에는 두가지가 있어요

String을 넣어서 돌리는방법

.js파일을 이용해서 돌리는 방법

 

 

    func fetchJS() {
        if let jsSourcePath = Bundle.main.path(forResource: "pracJSCore", ofType: "js") {
            do {
                let jsSourceContents = try String(contentsOfFile: jsSourcePath)
                self.context?.evaluateScript(jsSourceContents)
            }
            catch {
                print(error.localizedDescription)
            }
        }
    }

파일이름과 타입에 맞게 꺼내서

 

evaluateScript

자바스크립트 코드를 실행시켜주는 함수에요

실행하고나면 코드를 가져다 쓸 수 있어요

 

 

 

Swift에 있는 타입이나 구조체, 함수를

자바스크립트 코드에 넣어서 사용할 수 있도록 해줄 수 도있어요

Swift와 JavaScript사이에서 변수를 공유 할 수 있다는 뜻이에요

2가지 방법이 있어요

JSExport를 이용한 objc 클래스 정의

        unsafeBitCast를 이용한 swift 콜백함수 정의

 

 

JSContext.setObject(넣을 타입, forKeyedSubscript: 스크립트코드내에서 사용할 타입명)

 

 

 

첫번째Objc함수를 이용한 방법

자바스크립트에서 돌릴수있도록 타입을 구현

 

context?.setObject(TestA.self, forKeyedSubscript: "TestA" as (NSCopying & NSObjectProtocol))


@objc protocol TestJSExports: JSExport {
    func hello() -> String
    func yourName(_ name: String) -> String
    static func getInstance() -> TestA
}

class TestA: NSObject, TestJSExports {
    public func hello() -> String {
        return "Hello World!"
    }
    
    public func yourName(_ name: String) -> String {
        return "Hello, " + name + "!"
    }
    
    class func getInstance() -> TestA {
        return TestA()
    }
}

 

위와같은 타입의 인스턴스를 만들고

 

let jsValue1 = context?.evaluateScript(
    """
    (function(){
    var test = TestA.getInstance();
    return test.hello()})()
    """
)

위의 코드를 실행할 수 있는거에요

TestA는 Swift에서 정의한 타입인데 사용 할 수 있죠

 

 

 

두번째로 swift메소드로 구현

콜백함수를 작성하는거에요

 

//@convention -> swift 메소드의구현
let numbersHandler: @convention(block) ([Int]) -> Void = { numbers in
    print(numbers)
}

let numbersObject = unsafeBitCast(self.numbersHandler, to: AnyObject.self)
// Swift함수 numbersHandler를 자바스크립트에 handleNumbers 넣어주기
self.context?.setObject(numbersObject, forKeyedSubscript: "handleNumbers" as (NSCopying & NSObjectProtocol))

handler함수를 구현하고

AnyObejct타입으로 변환해서

자바스크립트코드에 넣어주고 사용할 수 있어요

 

 

 

 

 

이번에는 간단하게 맛보기(?) 처럼

JavaScriptCore가 어떤건지 느낌을 좀 알고

데이터를 넣는 방법을 했구요!!

 

 

다음에 JavaScript코드에서 원하는 변수, 값을 빼오는 연습을 해볼게요

 

 

 

반응형