News & Updates

How to Use the iOS Hacker News API: A Complete Guide

By Natalie Farrow 13 min read 3860 views

How to Use the iOS Hacker News API: A Complete Guide

If you’ve ever wanted to tap into the real‑time buzz of Hacker News right from an iOS app, the Hacker News API is your ticket. It’s not a secret service—just a public, well‑documented endpoint that lets you fetch stories, comments, and user profiles in JSON. This guide walks you through the essentials, from setting up network calls to handling pagination, and even shares a few shortcuts developers love.

What the Hacker News API Actually Offers

At its core, the API provides three main resources:

  • Items – stories, comments, polls, and jobs identified by a numeric ID.
  • Users – public profiles with karma, submitted stories, and about text.
  • Lists – top, new, best, ask, show, and job story IDs.

All responses are plain JSON, so you’ll be working with dictionaries and arrays rather than XML or custom formats. The base URL is https://hacker-news.firebaseio.com/v0/, and each endpoint ends with .json. For example, /topstories.json returns an array of the current top story IDs.

Getting Started in Xcode

First things first: you need a project that can make HTTPS requests. While URLSession works just fine, many developers reach for Alamofire to cut down boilerplate.

Sample URLSession Call

let url = URL(string: "https://hacker-news.firebaseio.com/v0/topstories.json")!

URLSession.shared.dataTask(with: url) { data, response, error in

guard let data = data, error == nil else { return }

if let ids = try? JSONDecoder().decode([Int].self, from: data) {

print("Top story IDs:", ids.prefix(10))

}

}.resume()

This snippet pulls the latest top story IDs and prints the first ten. From there, you’ll request each story’s details via /item/{id}.json.

Mapping JSON to Swift Models

Because the API’s payloads are fairly flat, a single struct can handle most item types. Notice the optional fields—some story attributes simply aren’t present for comments or polls.

struct HNItem: Decodable {

let id: Int

let title: String?

let url: String?

let text: String?

let kids: [Int]?

let score: Int?

let by: String?

let time: TimeInterval

let type: String

}

When you decode, you’ll get a fully typed object ready for UI binding. The time field is a Unix timestamp; convert it with Date(timeIntervalSince1970:) for a readable format.

Handling Pagination and Rate Limits

The API itself doesn’t enforce strict pagination—rather, you manage it on the client side. A common pattern is to request a batch of IDs (say, the first 30 from topstories.json) and then fetch each item in parallel. If you need “infinite scroll,” simply request the next slice of IDs when the user reaches the bottom.

As for rate limiting, the service is generous but not infinite. To stay friendly:

  • Cache results locally (Core Data, Realm, or even NSUserDefaults for tiny payloads).
  • Debounce rapid scroll events that would trigger dozens of network calls in a second.
  • Respect the Cache‑Control header; many endpoints send a max‑age of a few minutes.

Displaying Stories in a Table View

Here’s a quick outline of the flow:

  1. Fetch the list of IDs.
  2. Slice the array to the batch you need.
  3. Dispatch a group of fetches for each /item/{id}.json.
  4. Append the decoded HNItem objects to your data source.
  5. Reload the table view on the main thread.

A snippet using DispatchGroup illustrates step three:

let group = DispatchGroup()

var items: [HNItem] = []

for id in batchIDs {

group.enter()

let itemURL = URL(string: "https://hacker-news.firebaseio.com/v0/item/\(id).json")!

URLSession.shared.dataTask(with: itemURL) { data, _, _ in

defer { group.leave() }

guard let data = data,

let item = try? JSONDecoder().decode(HNItem.self, from: data) else { return }

items.append(item)

}.resume()

}

group.notify(queue: .main) {

self.stories = items.sorted { $0.time > $1.time }

self.tableView.reloadData()

}

Sorting by time ensures the newest stories appear first, even if network responses arrive out of order.

Fetching Comments Recursively

Comments are nested via the kids array, which contains child comment IDs. To display a thread, you’ll typically load the first level, then fetch deeper levels on demand (e.g., when the user taps “View replies”). Recursive fetching can quickly spiral, so a lazy approach keeps memory usage sane.

Lazy Loading Example

func loadChildren(of parent: HNItem, completion: @escaping ([HNItem]) -> Void) {

guard let childIDs = parent.kids else { completion([]); return }

var children: [HNItem] = []

let group = DispatchGroup()

for id in childIDs {

group.enter()

let url = URL(string: "https://hacker-news.firebaseio.com/v0/item/\(id).json")!

URLSession.shared.dataTask(with: url) { data, _, _ in

defer { group.leave() }

if let data = data,

let child = try? JSONDecoder().decode(HNItem.self, from: data) {

children.append(child)

}

}.resume()

}

group.notify(queue: .main) { completion(children) }

}

This function returns an array of immediate child comments, leaving deeper nesting to subsequent calls.

Working With User Profiles

Displaying a user’s karma or submitted stories follows the same pattern:

let userURL = URL(string: "https://hacker-news.firebaseio.com/v0/user/pg.json")!

URLSession.shared.dataTask(with: userURL) { data, _, _ in

guard let data = data,

let profile = try? JSONDecoder().decode(UserProfile.self, from: data) else { return }

print("\(profile.id) has \(profile.karma) karma")

}.resume()

Where UserProfile mirrors the API’s fields (id, karma, created, about, submitted).

Tips and Common Pitfalls

  • Don’t assume every story has a URL. Some “Ask HN” posts are text‑only, so check url before opening Safari.
  • Watch out for nil values. The JSON is sparse; many properties are optional, and trying to force‑unwrap will crash.
  • Cache images wisely. When a story includes a thumbnail, use Nuke or similar libraries that respect HTTP caching.
  • Be mindful of time zones. Converting Unix timestamps to the user’s local time improves readability.

Wrapping Up

Integrating the Hacker News API into an iOS app is surprisingly straightforward once you grasp the three‑step flow: fetch IDs, pull item details, and render them. By leveraging Swift’s Decodable protocol, modern concurrency tools, and a bit of caching, you can build a responsive, news‑rich experience that feels native.

Give it a try—pick a list (top, newest, or ask), display the first batch, and watch how quickly users start digging into the discussions that shape the tech community.

GitHub - cmcgheit/Hacker-News-Reader: Hacker News Reader for iOS
GitHub - cmcgheit/Hacker-News-Reader: Hacker News Reader for iOS
Hacker news api 접속 오류 - 인프런 | 커뮤니티 질문&답변
The Complete Guide to Securing iOS Applications Against Hackers ...

Written by Natalie Farrow

Natalie Farrow is a Chief Correspondent with over a decade of experience covering breaking trends, in-depth analysis, and exclusive insights.