커스텀스키마나 URL의 파라메터 Dictionary로 변경

 

import Foundation

extension URL {
    /// URL의 파라메터 값을 Dictionary로 변경
    var queryDictionary: [String: String]? {
        guard let query = self.query else { return nil}

        var queryStrings = [String: String]()
        for pair in query.components(separatedBy: "&") {

            let key = pair.components(separatedBy: "=")[0]

            let value = pair
                .components(separatedBy:"=")[1]
                .replacingOccurrences(of: "+", with: " ")
                .removingPercentEncoding ?? ""

            queryStrings[key] = value
        }
        return queryStrings
    }
    
    /*
     app://open?target_url=%22https://m.xxxxx.co.kr:4112/s/sso/login?token=NRg9qgitQExqgyiAxXGF-r1gBG6vdaPep8zuh0E6UTE=&app=Y%22
     target_url의 전체 구문을 분리하려면 %22로 감싸서 분리해서 그대로 웹뷰로 로딩
     
     ** URL String 에 #이 있을 경우 query 에서 짤림 주의.
     */
    var queryUrlDictionary: [String: String]? {
        guard let query = self.query else { return nil}

        var queryStrings = [String: String]()
        let pair = query.components(separatedBy: "%22")
        
        if let key = pair[safe: 0]?.replacingOccurrences(of: "=", with: ""),
            let value = pair[safe: 1] {
            
            queryStrings[key] = value
        }
      
        return queryStrings
    }
    
    /*
    참고사이트 : http://www.seanbehan.com/how-to-parse-url-parameters-in-swift/
         URL(string:"http://example.com/?x=1&y=2").params()
         ["x" : 1, "y": 2]
    */
    ///사용자 EXTENSION : URL의 파라메터값을 분리 해서 딕셔너리로 리턴
    func params() -> [String:Any] {
        var dict = [String:Any]()
        
        if let components = URLComponents(url: self, resolvingAgainstBaseURL: false) {
            if let queryItems = components.queryItems {
                for item in queryItems {
                    dict[item.name] = item.value!
                }
            }
            return dict
        } else {
            return [:]
        }
    }
}

사용방법

 

ex1) myapp://externalBrowser?url=https://naver.com&target=abcd

 

func schemeMessageHandler(schemeUrl: URL) {
        
        if let scheme = schemeUrl.scheme {
            switch scheme {
            case "myapp":
                if let function = schemeUrl.host {
                    let selector = Selector(function+":")
                    let originalMethod = class_getInstanceMethod(MainViewController.self, selector)
                    if originalMethod == nil {
                        log(direction: .ERROR, ofType: self, datas: "Scheme->Native \(selector) : 호출할 수 없는 함수 입니다.")
                        return
                    }
                    
                    let param = schemeUrl.queryDictionary
                    perform(selector, with: param)
                }
            default: break
            }
        }
 }

 

ex2) URL(string:"http://example.com/?x=1&y=2").params()

        결과 :  ["x" : 1, "y": 2]

+ Recent posts