如何以 JSON 格式返回 Glassdoor API

Posted

技术标签:

【中文标题】如何以 JSON 格式返回 Glassdoor API【英文标题】:How To Return Glassdoor API in JSON Format 【发布时间】:2017-11-03 20:23:31 【问题描述】:

我在返回 https://www.glassdoor.com/developer/companiesApiActions.htm 此处找到的 Glassdoor API 时遇到了一些困难

如何以 JSON 格式返回整个公司,以便我可以显示公司信息以及 CEO 信息。

到目前为止,我可以显示公司信息,但无法访问 CEO 数据和 featureReview 数据。

这就是我提出请求但不完全以 JSON 格式返回结果的方式。

Alamofire.request(glassdoorURL).responseJSON  (response) in
print("================")

//if let JSON = response.result.value as? [String:AnyObject]  
//dictionary
    //print("JSON: \(JSON)")
    //let employers = JSON["response"]!["employers"]!! as [[String:AnyObject]]

if let JSON = response.result.value as? [String:Any]  //dictionary

if let resp = JSON["response"] as?[String:Any]   //dictionary

let employers = resp["employers"] as?[[String:Any]] //array

    print("Employers: \(employers!)")

     self.companies = self.filterCompanies(companyArray: employers!)  
  //takes the company and puts it into an array to display to a table

     self.researchTableView.reloadData()
 
//

print("================")

这是我的数据模型。

final class GlassdoorCompany: NSObject 

var name: String? 
var websiteURL: String?
var industry: String?
var logo: String?
var overallRating: String?
var ceo: Ceo?
var featuredReview: FeaturedReview?

init(fromJSON json: NSDictionary) 
    if let nameStr = json["name"] as? String 
        self.name = nameStr
    
    if let websiteURLStr = json["website"] as? String 
        self.websiteURL = websiteURLStr
    
    if let industryStr = json["industry"] as? String 
        self.industry = industryStr
    
    if let logoStr = json["squareLogo"] as? String 
        self.logo = logoStr
    
    if let overallRatingStr = json["overallRating"] as? String 
        self.overallRating = overallRatingStr
    
    if let ceoStr = json["ceo"] as? Ceo 
        self.ceo = ceoStr
    
    if let featuredReviewStr = json["featuredReview"] as? 
 FeaturedReview 
        self.featuredReview = featuredReviewStr
    


final class Ceo: NSObject 

var name: String?
var image: ceoImage?
var approvalRating: Int?
var disapprovalRating: Int?
var totalRatings: Int?

init?(fromJSON json: NSDictionary)

    if let nameStr = json["name"] as? String 
        self.name = nameStr
    

    if let imageStr = json["image"] as? ceoImage 
        self.image = imageStr
    

    if let approvalRatingStr = json["pctApprove"] as? Int 
        self.approvalRating = approvalRatingStr
    

    if let disapprovalRatingStr = json["pctDisapprove"] as? Int 
        self.disapprovalRating = disapprovalRatingStr
    

    if let totalRatingsStr = json["numberOfRatings"] as? Int 
        self.totalRatings = totalRatingsStr
    


final class ceoImage: NSObject 

var height: Int?
var src: String?
var width: Int?

init?(fromJSON json: NSDictionary) 

    if let heightStr = json["height"] as? Int 
        self.height = heightStr
    

    if let srcStr = json["src"] as? String 
        self.src = srcStr
    

    if let widthStr = json["width"] as? Int 
        self.width = widthStr
    


final class FeaturedReview 
var currentJob: Bool?
var reviewDate: String?
var jobTitle: String?
var location: String?
var headline: String?
var pros: String?
var cons: String?
var overallRating: Int?

init?(fromJSON json: NSDictionary) 

    if let currentJobStr = json["currentJob"] as? Bool 
        self.currentJob = currentJobStr
    

    if let reviewDateStr = json["reviewDateTime"] as? String 
        self.reviewDate = reviewDateStr
    

    if let jobTitleStr = json["jobTitle"] as? String 
        self.jobTitle = jobTitleStr
    

    if let locationStr = json["location"] as? String 
        self.location = locationStr
    

    if let headlineStr = json["headline"] as? String 
        self.headline = headlineStr
    

    if let prosStr = json["pros"] as? String 
        self.pros = prosStr
    

    if let consStr = json["cons"] as? String 
        self.cons = consStr
    

    if let overallRatingStr = json["overall"] as? Int 
        self.overallRating = overallRatingStr
    

【问题讨论】:

【参考方案1】:

您遇到的问题是无法直接将 json 对象直接转换为 swift 类。所以json["ceo"] as? Ceojson["featuredReview"] as? FeaturedReview 只是返回nil。所以你需要改变你初始化类的方式。

我已经重写了你的 CeoCeoImage 类,你只需要在此基础上修复 FeaturedReview。我还添加了一个 Swift 4 Codable 示例,我建议您应该学习使用它,因为它现在变得非常流行并且简单得多。

在下面实现新的Ceo模型后,改变

if let ceoStr = json["ceo"] as? Ceo 
    self.ceo = ceoStr

if let ceoStr = Ceo(json["ceo"] as? Dictionary<String,Any>) 
    self.ceo = ceoStr

您需要解决的问题

struct Ceo 

    let name: String
    let image: CeoImage
    let approvalRating: Int
    let disapprovalRating: Int
    let totalRatings: Int

    init?(_ dict: Dictionary<String,Any>?)

        guard
            let name = dict["name"] as? String,
            let image = CeoImage(dict["image"] as? Dictionary<String,Any>),
            let approvalRating = dict["pctApprove"] as? Int,
            let disapprovalRating = dict["pctDisapprove"] as? Int,
            let totalRatings = dict["numberOfRatings"] as? Int
        else 
            return nil
        
        self.name = name
        self.image = image
        self.approvalRating = approvalRating
        self.disapprovalRating = disapprovalRating
        self.totalRatings = totalRatings
    


struct CeoImage 

    let height: Int
    let src: String
    let width: Int

    init?(_ dict: Dictionary<String,Any>?) 
        guard
            let height = dict?["height"] as? Int,
            let src = dict?["src"] as? String,
            let width = dict?["width"] as? Int
        else 
            return nil
        
        self.height = height
        self.src = src
        self.width = width
    

Swift 4 可编码示例

class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        Alamofire.request(glassdoorURL).responseJSON  (response) in

            // We need to extract the `response` data from the json and convert
            // it back to `Data` for the JSONDecoder
            guard
                let dict = response.result.value as? Dictionary<String,Any>,
                let responseData = dict["response"] as? Dictionary<String,Any>,
                let json = JSONSerialization.data(withJSONObject: responseData)
            else 
                return
            

            do 
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SS"

                let decoder = JSONDecoder()
                decoder.dateDecodingStrategy = .formatted(dateFormatter)
                let company = try decoder.decode(Company.self, from: json)
                dump(company)
             catch 
                print("\n(error)\n")
            
        
    

型号

struct Company: Codable 

    let employers: Array<Employer>


struct Employer: Codable 

    let name: String
    let website: URL
    let industry: String
    let squareLogo: URL
    let overallRating: Int
    let ceo: CEO
    let featuredReview: FeaturedReview


struct CEO: Codable 

    struct CEOImage: Codable 
        let src: URL
        let height: Int
        let width: Int
    

    let name: String
    let title: String
    let image: CEOImage
    let numberOfRatings: Int
    let pctApprove: Int
    let pctDisapprove: Int


struct FeaturedReview : Codable 

    let id: Int
    let currentJob: Bool
    let reviewDateTime: Date
    let jobTitle: String
    let location: String
    let headline: String
    let pros: String
    let cons: String

【讨论】:

我根据他们网站上的 IBM 示例测试了所有这些。因此,我没有测试 Alamofire 实际响应的内容,因为他们希望您请求 API 密钥,但它应该可以工作。 感谢您的回复!我意识到我的错误,我习惯于将对象投射到领域数据库中!非常有帮助和详细的答案。

以上是关于如何以 JSON 格式返回 Glassdoor API的主要内容,如果未能解决你的问题,请参考以下文章

如何以自定义 json 格式返回数据?

React - 如何以 JSON 格式返回 HTML 元素

如何以 JSON 格式获取元素的样式?

如何以json格式从类返回非空属性[重复]

如何使 WCF 数据服务查询拦截器以 JSON 格式返回结果?

java - 如何在java中使用restful api以json格式返回404?