Home > OS >  Count number of objects in JSON array on a URL in swift5
Count number of objects in JSON array on a URL in swift5

Time:02-13

I have a JSON array at url = https://api.github.com/users/greenrobot/starred .
I want to count how many objects are there in that array using swift. I don't want data present, I just want count of it.

CodePudding user response:

Assuming you downloaded the contents of that URL into a variable data of type Data:

if let object = try? JSONSerialization.jsonObject(with: data, options: []) as? [[String: AnyHashable]] {
    let count = object[0].keys.count
}

CodePudding user response:

I assume that you are using Alamofire for making a network request. In the code below we are just extracting the value object from Alamofire result. We convert the value to Array of dictionaries and then you can just get the count.

AF.request("https://api.github.com/users/greenrobot/starred",method: .get).responseJSON { apiResponse in
        switch apiResponse.result{
        case .success(_):
            let dictionary = apiResponse.value as? [[String:Any]]
            print("dictionaryCount \(dictionary?.count ?? -1)")
        case .failure(_):
            print("error \(apiResponse.error?.underlyingError?.localizedDescription ?? "")")
        }
    }

CodePudding user response:

The GitHub starred API returns a maximum of 30 items by default, in the case of greenrobot with a total number of 372 it's not meaningful.

A smart way to get the actual number of starred items is to specify one item per page and to parse the Link header of the HTTP response which contains the number of the last page

Task {
    do {
        let url = URL(string: "https://api.github.com/users/greenrobot/starred?per_page=1")!
        let (_, response) = try await URLSession.shared.data(from: url)
        guard let link = (response as? HTTPURLResponse)?.value(forHTTPHeaderField: "Link") else {
            throw URLError(.badServerResponse)
        }
        let regex = try NSRegularExpression(pattern: "page=(\\d )")
        if let lastMatch = regex.matches(in: link).last {
            let range = Range(lastMatch.range(at: 1), in: link)!
            let numberOfStarredItems = String(link[range])
            print(numberOfStarredItems)
        } else {
            print("No match found")
        }
    } catch {
        print(error)
    }
}
  • Related