Swift(iOS)/Information

iOS ↔ Typescript 함수 공유 방법 (2)

y0ngha 2021. 10. 27. 00:42

이 전에, 기술했던 내용에 이어서 작성을 하도록 한다.

 

이 전 예제에서는 리턴 값이 없었을 때에 함수 작성 방법이었고, 만약 iOS Native Application 상에서 특정 액션을 통해 값을 만들고 난 후 이 값을 Web Application으로 Return을 해줄 때의 방법이다.

(사실 이 방법이 맞는지는 모르겠으나, 생각했을 때 이 방법밖에 생각나지 않아 이런식으로 작성하였다.. 나중엔 더 좋은 코드가 있는지 찾아봐야한다.)

 

이 전에서는 setPreference에 대한 내용을 기술했으니, 이번에는 getPreference를 진행하여 값을 받아오는 방법에 대해 기술한다.

 

setPreference 함수가 정상적으로 작동을 했다면, iOS Application Preference 공간에 [Key: Value] 형식으로 데이터가 잘 들어가 있으리라 기대할 수 있다.

 

이것을 빼오려면 Swift에서 'let data = self.preferences.string(forKey: _key)!' 함수를 호출하면 '_key' 에 맞는 value를 가져올 수 있다.

 

이제 이것을 Web Application으로 Return하는 방법에 대해 작성한다.

 

이전에 작성했던 NativeService.ts → Native Interface에 추가되는 함수 원형이다.

1
getPref: (key: string, defaultData: string=> Promise<string>;
cs

이전에 작성했던 ViewController.swift → UserContentController 함수에다가 이어 작성한 부분이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
case "getPref":
    if let _key = dictionary["key"] {
        if _key == "" {
            let alert = UIAlertController(title: "알림", message: "[오류] 웹 오류 발생\nKEY가 빈값입니다.", preferredStyle: UIAlertController.Style.alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!in
            }))
            self.present(alert, animated: true, completion: nil)
        } else {
            if let _defaultData = dictionary["defaultData"] {
                var data = _defaultData
                
                if self.preferences.object(forKey: _key) != nil {
                    data = self.preferences.string(forKey: _key)!
                }
                self.evaluateJavascript(script: "window.\(_key) = '\(data)'");
            } else {
                let alert = UIAlertController(title: "알림", message: "[오류] 웹 오류 발생\n기본값을 찾을 수 없습니다.", preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!in
                }))
                self.present(alert, animated: true, completion: nil)
            }
        }
    } else {
        let alert = UIAlertController(title: "알림", message: "[오류] 웹 오류 발생\nKEY를 찾을 수 없습니다.", preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!in
        }))
        self.present(alert, animated: true, completion: nil)
    }
    
    break;
cs

가장 핵심적인 부분은 15번째 줄이다.

data를 불러오고 나서, 이 data를 리턴해야하는데 iOS에서 return 하는 방법을 찾아도 찾아도 안나오길래, 어쩔 수 없이 window라는 global 변수 안에다가 넣어준 것이다.

 

Process는 아래와 같이 흘러간다.

  1. Web Application에서 'getPref' 함수를 호출
  2. getPref 함수가 호출되면, Native에 들어가게 되고 여러 데이터 검증을 진행.
    (key가 Empty가 아닌지, optional binding을 통해 dictionary에 있는 값이 정상적인지 체크)
  3. 전부 다 정상이라면 _key에 대해 Preference에 저장되어 있는 value를 가져오고, 해당 value를 *evaluateJavascript 함수를 통해 window object 안에다가 넣어주는 작업을 진행
    (*evaluateJavascript ? → Javascript를 실행하는 함수)

그리고 이 함수를 만들때의 주의점은 항상 await을 걸어서 동기식 처리를 해야한다.

동기처리를 진행하지 않으니, 함수는 끝났는데 window에는 값이 없는 상황이 발생한다.