mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-20 19:33:08 +09:00
78 lines
3.1 KiB
Swift
78 lines
3.1 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import Alamofire
|
|
import Foundation
|
|
import Shared
|
|
|
|
let SearchSuggestClientErrorDomain = "org.mozilla.firefox.SearchSuggestClient"
|
|
let SearchSuggestClientErrorInvalidEngine = 0
|
|
let SearchSuggestClientErrorInvalidResponse = 1
|
|
|
|
/*
|
|
* Clients of SearchSuggestionClient should retain the object during the
|
|
* lifetime of the search suggestion query, as requests are canceled during destruction.
|
|
*
|
|
* Query callbacks that must run even if they are cancelled should wrap their contents in `withExtendendLifetime`.
|
|
*/
|
|
class SearchSuggestClient {
|
|
fileprivate let searchEngine: OpenSearchEngine
|
|
fileprivate weak var request: Request?
|
|
fileprivate let userAgent: String
|
|
|
|
lazy fileprivate var alamofire: SessionManager = {
|
|
let configuration = URLSessionConfiguration.ephemeral
|
|
var defaultHeaders = SessionManager.default.session.configuration.httpAdditionalHeaders ?? [:]
|
|
defaultHeaders["User-Agent"] = self.userAgent
|
|
configuration.httpAdditionalHeaders = defaultHeaders
|
|
return SessionManager(configuration: configuration)
|
|
}()
|
|
|
|
init(searchEngine: OpenSearchEngine, userAgent: String) {
|
|
self.searchEngine = searchEngine
|
|
self.userAgent = userAgent
|
|
}
|
|
|
|
func query(_ query: String, callback: @escaping (_ response: [String]?, _ error: NSError?) -> Void) {
|
|
let url = searchEngine.suggestURLForQuery(query)
|
|
if url == nil {
|
|
let error = NSError(domain: SearchSuggestClientErrorDomain, code: SearchSuggestClientErrorInvalidEngine, userInfo: nil)
|
|
callback(nil, error)
|
|
return
|
|
}
|
|
|
|
request = alamofire.request(url!)
|
|
.validate(statusCode: 200..<300)
|
|
.responseJSON { response in
|
|
if let error = response.result.error {
|
|
callback(nil, error as NSError?)
|
|
return
|
|
}
|
|
|
|
// The response will be of the following format:
|
|
// ["foobar",["foobar","foobar2000 mac","foobar skins",...]]
|
|
// That is, an array of at least two elements: the search term and an array of suggestions.
|
|
let array = response.result.value as? NSArray
|
|
if array?.count ?? 0 < 2 {
|
|
let error = NSError(domain: SearchSuggestClientErrorDomain, code: SearchSuggestClientErrorInvalidResponse, userInfo: nil)
|
|
callback(nil, error)
|
|
return
|
|
}
|
|
|
|
let suggestions = array?[1] as? [String]
|
|
if suggestions == nil {
|
|
let error = NSError(domain: SearchSuggestClientErrorDomain, code: SearchSuggestClientErrorInvalidResponse, userInfo: nil)
|
|
callback(nil, error)
|
|
return
|
|
}
|
|
|
|
callback(suggestions!, nil)
|
|
}
|
|
|
|
}
|
|
|
|
func cancelPendingRequest() {
|
|
request?.cancel()
|
|
}
|
|
}
|