

`SwiftUI`で、`API`接続でデータを取得し利用するアプリを開発しています。

SwiftUIで開発中のアプリから、API接続でGETの方法でデータを取得する際に、検索条件のパラメーターが`&`や`=`を含む文字列になる場合、データを取得することができません。

* * *

例えば、  
`http://sample.com/api/book/`  
というベースのエンドポイントがあり、`?url=`というように、URLの文字列を検索の条件とする場合：

①：以下のようにパラメーターを設定すると値が取得できますが、  
[http://sample.com/api/book/?url=`https://nicebook.com/detail/id/106639`](http://sample.com/api/book/?url=%60https://nicebook.com/detail/id/106639%60)

②：以下の場合は取得できません  
[http://sample.com/api/book/?url=`https://nicebook.com/detail/?id=106639&category=history`](http://sample.com/api/book/?url=%60https://nicebook.com/detail/?id=106639&category=history%60)

②の場合、パラメーターとして設定している文字列に`?`,`=`の記号が含まれ、こちらも検索の条件とされてしまい、期待している動きにならないと思うのですが、このような場合どのような対策方法があるでしょうか？

* * *

API接続時のコードは以下のとおりです。

[code]

    func fetchApiData() {
    
        let url_1 = "https://nicebook.com/detail/id/106639"
        let url_2 = "https://nicebook.com/detail/?id=106639&category=history"
    
        var endpoint = "http://sample.com/api/book/?url=" + url_1 // OK
        // var endpoint = "http://sample.com/api/book/?url=" + url_2 NG
    
        var encodeEndpoint = endpoint.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
    
        // Set up the URL request
        guard let url = URL(string: encodeEndpoint) else {
            print("Error: cannot create URL")
            return
        }
        let urlRequest = URLRequest(url: URL)
    
        // set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
    
        // make the request
        let task = session.dataTask(with: urlRequest) {
            (data, response, error) in
    
            // check for any errors
            guard error == nil else {
                print("error calling GET")
                return
            }
            // make sure we got data
            guard let responseData = data else {
                print("Error: did not receive data")
                return
            }
    
            // parse the result as JSON, since that's what the API provides
            DispatchQueue.main.async {
                do{ self.bookInfos = try JSONDecoder().decode([BookInfo].self, from: responseData)
                    print(self.bookInfos as Any) // url_2で行うと値が取れない（コンソール -> []）
                }catch{
                    print("Error: did not decode")
                    return
                }
            }
        }
        task.resume()
    }
    
[/code]

* * *

[こちら](https://qiita.com/yum_fishing/items/db029c097197e6b27fba)の記事を参考に、パラメーターとなるURLのエンコードを別にエンコードする方法も試しましたが、うまく取得できません。

[code]

    let url_2 = "https://nicebook.com/detail/?id=106639&category=history"
    url_2.addEndpoint.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
    var endpoint = "http://sample.com/api/book/?url=" + url_2
    
    var encodeEndpoint = endpoint.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
    
[/code]

* * *

Swift 5.0


CC BY-SA 4.0
2021-08-05T03:13:56.597
80606
2021-08-05T04:00:54.853
36988
question
swift api
`&`や`=`を含む文字列を検索条件のパラメーターにするとAPI接続で値が取得できない


下記のように編集する事でかいけつできました。

[code]

    var urlComps = URLComponents(string: endpoint)!
    urlComps.queryItems = [URLQueryItem(name: "url", value: url_2)]
    guard let url = urlComps.url else {
        print("Error: cannot create URL")
        return
    }
    
[/code]


CC BY-SA 4.0
2021-08-05T04:00:54.853
80607
2021-08-05T04:00:54.853
36988
80606
answer