├── .gitignore ├── CNAME ├── LICENSE ├── README.md └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | postcode.pocketlesson.io -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 PocketLesson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Daum Postcode 2 | 3 | [다음 우편번호 서비스](https://postcode.map.daum.net/guide)를 별도의 패키지 설치 없이도 네이티브 앱에서 쉽게 사용할 수 있습니다. 4 | 5 | ## 사용 방법 6 | 7 | 1. 웹뷰를 사용해서 https://postcode.pocketlesson.io URL을 로드합니다. 8 | 2. 로드된 웹뷰에서 주소를 선택하면 `postcode://` URL scheme과 `webkit.messageHandlers.postcode` 핸들러를 통해 메시지가 전달됩니다. 9 | 10 | ## API 11 | 12 | ### Query Parameters 13 | 14 | | 이름 | 설명 | 예시 | 15 | |---|---|---| 16 | | query | 검색어 (Optional) | `역삼로 180` | 17 | 18 | ### Callback Data 19 | 20 | 콜백은 두 가지 방식으로 제공됩니다. 21 | 22 | 1. URL Scheme 23 | `postcode://complete?=&...` 형태로 제공됩니다. 24 | 2. Message Handler 25 | `{key: value, ...}` 형태로 제공됩니다. 26 | 27 | 자세한 데이터는 [다음 우편번호 서비스 문서](https://postcode.map.daum.net/guide#attributes)를 참고해 주세요. 28 | 29 | ## 사용 예시 30 | 31 | ### iOS 32 | 33 | #### URL Scheme 34 | 35 | ```swift 36 | let webView = WKWebView() 37 | webView.navigationDelegate = self 38 | 39 | let url = URL(string: "https://postcode.pocketlesson.io")! 40 | webView.load(URLRequest(url: url)) 41 | 42 | func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { 43 | switch navigationAction.request.url?.scheme { 44 | case "postcode": 45 | if let urlString = navigationAction.request.url?.absoluteString { 46 | let components = URLComponents(string: urlString) 47 | let address = components?.queryItems?.first { $0.name == "address" }?.value 48 | let zonecode = components?.queryItems?.first { $0.name == "zonecode" }?.value 49 | print(address) // e.g. 서울 강남구 역삼로 180 50 | print(zonecode) // e.g. 06248 51 | } 52 | decisionHandler(.cancel) 53 | 54 | default: 55 | decisionHandler(.allow) 56 | } 57 | } 58 | ``` 59 | 60 | #### Message Handler 61 | 62 | ```swift 63 | let webView = WKWebView() 64 | webView.configuration.userContentController.add(PostcodeHandler(), name: "postcode") 65 | 66 | let url = URL(string: "https://postcode.pocketlesson.io")! 67 | webView.load(URLRequest(url: url)) 68 | 69 | class PostcodeHandler: NSObject, WKScriptMessageHandler { 70 | func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { 71 | guard let data = message.body as? [String: Any] else { return } 72 | let address = data["address"] as? String // e.g. 서울 강남구 역삼로 180 73 | let zoneCode = data["zonecode"] as? String // e.g. 06248 74 | } 75 | } 76 | ``` 77 | 78 | ### React Native 79 | 80 | #### URL Scheme 81 | 82 | ```tsx 83 | const parseQueryParams = () => { 84 | const search = path.split('?')[1] 85 | if (!search) { 86 | return {} 87 | } 88 | 89 | let params: Record = {} 90 | 91 | const items = search.split('&') 92 | items.forEach((item) => { 93 | const [key, value] = item.split('=') 94 | params[key] = decodeURIComponent(value) 95 | }) 96 | return params 97 | } 98 | 99 | const PostcodeSearchScreen = () => ( 100 | { 105 | if (request.url.startsWith('postcode://')) { 106 | const data = parseQueryParams(request.url) 107 | 108 | console.log(data?.address) // e.g. 서울 강남구 역삼로 180 109 | console.log(data?.zonecode) // e.g. 06248 110 | return false 111 | } 112 | return true 113 | }} 114 | /> 115 | ) 116 | ``` 117 | 118 | ## 라이선스 119 | 120 | 이 소스코드 저장소에 속한 코드는 MIT 라이선스를 따릅니다. 다음 우편번호 서비스와 관련한 소유권과 저작권은 카카오에 있습니다. 121 | 122 | 로딩 인디케이터의 애니메이션은 [react-native-web](https://github.com/necolas/react-native-web)의 것을 사용했습니다. 123 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 99 | 100 | 101 | --------------------------------------------------------------------------------