I am having some difficulties return the Glassdoor API found here https://www.glassdoor.com/developer/companiesApiActions.htm
How Can I return the entire company in JSON format So that I can display the company information as well as the ceo information.
So far I can display the company Information but I cannot access the Ceo data and featureReview data.
This is how I am making the Request but does not return the result entirely in 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("================")
}
This is my Data Model.
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
}
}
The problem you have is that it is not possible to directly cast json objects straight to a swift class. So json["ceo"] as? Ceo
and json["featuredReview"] as? FeaturedReview
are just returning nil
. So you need to change the way you have your class initialised.
I have rewritten your Ceo
and CeoImage
classes to work, you'll just need to fix the FeaturedReview
based on this. I have also added a Swift 4 Codable example which I recommend you should learn to use, since it is now becoming very popular and is a lot simpler.
After implementing the new Ceo
model below, change
if let ceoStr = json["ceo"] as? Ceo {
self.ceo = ceoStr
}
to
if let ceoStr = Ceo(json["ceo"] as? Dictionary<String,Any>) {
self.ceo = ceoStr
}
What you need to fix
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 Codable Example
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")
}
}
}
}
Model
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
}