如何在 iOS swift 中做产品搜索 api?

Posted

技术标签:

【中文标题】如何在 iOS swift 中做产品搜索 api?【英文标题】:How to do product search api in iOS swift? 【发布时间】:2018-06-15 04:07:52 【问题描述】:

我正在使用亚马逊产品广告 api 搜索产品。安装了 awscore 和 alamofire cocopods。完成了获取签名的功能,并为项目搜索添加了参数,以在表格视图列表中获取产品图像、标题和描述。

这是我尝试获取亚马逊搜索的代码:

     private func signedParametersForParameters(parameters: [String: String]) -> [String: String] 
    let sortedKeys = Array(parameters.keys).sorted(by: <)

    let query = sortedKeys.map  String(format: "%@=%@", $0, parameters[$0] ?? "") .joined(separator: "&")

    let stringToSign = "GET\nwebservices.amazon.in\n/onca/xml\n\(query)"
    print("stringToSign::::\(stringToSign)")

    let dataToSign = stringToSign.data(using: String.Encoding.utf8)
    let signature = AWSSignatureSignerUtility.hmacSign(dataToSign, withKey: CameraViewController.kAmazonAccessSecretKey, usingAlgorithm: UInt32(kCCHmacAlgSHA256))!

    var signedParams = parameters;
    signedParams["Signature"] = urlEncode(signature)
    print("urlencodesignature::\(urlEncode(signature))")

    return signedParams


public func urlEncode(_ input: String) -> String 
    let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)

    if let escapedString = input.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) 
        return escapedString
    

    return ""

func send(url: String) -> String 
 //        activityIndicator.startAnimating()
    guard let url = URL(string: url) else 
        print("Error! Invalid URL!") //Do something else
 //            activityIndicator.stopAnimating()
        return ""
    
    print("send URL: \(url)")
    let request = URLRequest(url: url)
    let semaphore = DispatchSemaphore(value: 0)

    var data: Data? = nil

    URLSession.shared.dataTask(with: request)  (responseData, _, _) -> Void in
        data = responseData

        print("send URL session data: \(String(describing: data))")
        let parser = XMLParser(data: data!)
        parser.delegate = self as? XMLParserDelegate
        if parser.parse() 
            print(self.results ?? "No results")
        
        semaphore.signal()

        .resume()

 //        activityIndicator.stopAnimating()
    semaphore.wait(timeout: .distantFuture)

    let reply = data.flatMap  String(data: $0, encoding: .utf8)  ?? ""
    return reply


public func getSearchItem(searchKeyword: String) -> [String:AnyObject]

    let timestampFormatter: DateFormatter
    timestampFormatter = DateFormatter()
    timestampFormatter.timeZone = TimeZone(identifier: "GMT")
    timestampFormatter.dateFormat = "YYYY-MM-dd'T'HH:mm:ss'Z'"
    timestampFormatter.locale = Locale(identifier: "en_US_POSIX")

//        let responsegroupitem: String = "ItemAttributes"
//        let responsegroupImages:String = "Images"

//        activityIndicator.startAnimating()
    let operationParams: [String: String] = [
        "Service": "AWSECommerceService",
        "Operation": "ItemSearch",
        "ResponseGroup": "Images,ItemAttributes",
        "IdType": "ASIN",
        "SearchIndex":"All",
        "Keywords": searchKeyword,
        "AWSAccessKeyId": urlEncode(CameraViewController.kAmazonAccessID),
        "AssociateTag": urlEncode(CameraViewController.kAmazonAssociateTag),
        "Timestamp": urlEncode(timestampFormatter.string(from: Date()))]

    let signedParams = signedParametersForParameters(parameters: operationParams)



    let query = signedParams.map  "\($0)=\($1)" .joined(separator: "&")
    let url = "http://webservices.amazon.in/onca/xml?" + query
    print("querydata::::\(query)")

    let reply = send(url: url)
    print("reply::::\(reply)")
 //        activityIndicator.stopAnimating()



    return [:]

创建桥接头文件#import .

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 

  getSearchItem(searchKeyword: searchKeyword)


这是我的控制台输出:

我的问题是点击搜索按钮时搜索的产品未列出。犯了什么错误我不知道。谁能帮我解决这个问题..

【问题讨论】:

【参考方案1】:

根据documentation:

HTTPRequestURI 组件是 URI 的 HTTP 绝对路径组件,直到但不包括查询字符串。如果 HTTPRequestURI 为空,请使用正斜杠 ( / )。

对于产品广告 API,HTTPRequestURI 始终为“/onca/xml”。 HTTPVerb 是 GET 或 POST。

尝试将 requestURL 设置为“/onca/xml”而不是完整的 URL,您不应该在这部分发送完整的 URL 或查询字符串。

您还需要对要发送的值进行百分比编码。您在响应组属性中发送逗号,应该是百分比编码

let operationParams: [String: String] = [
    "Service": "AWSECommerceService",
    "Operation": "ItemSearch",
    "ResponseGroup": urlEncode("Images,ItemAttributes"),
    "IdType": "ASIN",
    "SearchIndex":"All",
    "Keywords": urlEncode(searchKeyword),
    "AWSAccessKeyId": urlEncode(CameraViewController.kAmazonAccessID),
    "AssociateTag": urlEncode(CameraViewController.kAmazonAssociateTag),
    "Timestamp": urlEncode(timestampFormatter.string(from: Date()))]

let stringToSign = "GET\n/onca/xml\n\(query)"

注意:您应该使用 https 而不是 http

【讨论】:

感谢您的回答!!当“ResponseGroup”:“Images”,值只是图像意味着将从亚马逊获取数据,或者如果“ResponseGroup”:“Images,ItemAttributes,Offers”,值类似于图像,提供意味着签名失败时,实际上没有数据到来。 非常抱歉。我也更新了我的问题和控制台输出图像 我已经用一些不同的建议更新了答案。请删除与以前版本答案相关的 cmets。 可以有样品 再次更新答案

以上是关于如何在 iOS swift 中做产品搜索 api?的主要内容,如果未能解决你的问题,请参考以下文章

如何以正确的方式在 IOS SWIFT 3 中解析 Google 距离矩阵 API JSON

如何使用 Google Calendar API iOS Swift 创建事件

使用百度地图api在jsp中做地图,搜索结果中的图标样式怎么会变成这样?

iOS - 如何在 swift 中使用`NSMutableString`

如何在 iOS 中搜索时显示建议?

如何在swift 3中做障碍