[Server-Side Swift] Summarize information/articles for iOS with Vapor

Yoki
3 min readDec 26, 2021
Photo by Jayden Yoon ZK on Unsplash

What I created

yyokii/AppleDeveloperNews

  • Summary of information for Apple developers, especially iOS app developers.
  • Automatically updated every Sunday.

Motive

  • I wanted to try out Vapor.
  • I wanted to use Async/Await.
  • I want to follow the information I’m interested in regularly.

Technical points

Async/Await

Vapor incorporates SwiftNIO to support asynchronous programming. However, since Swift 5.5, the Concurrency language feature has been added so that you can write using the async/await keywords.

For example, suppose we have the following SwiftNIO-based EventLoopFuture based description

return someMethodCallThatReturnsAFuture().flatMap { futureResult in
// use futureResult
}

It can be rewritten as follows ( Vapor: Basics → Async migrating-to-asyncawait)

let futureResult = try await someMethodThatReturnsAFuture().get()

The following is a description of which writing style is better.

For applications that need explicit control over event loops, or very high performance applications, you should continue to use EventLoopFutures until custom executors are implemented. For everyone else, you should use async/await as the benefits or readability and maintainability far outweigh any small performance penalty

Vapor: Basics → Async

It would be good to try out Vapor as a catch-up for Concurrency.
Also, if you’re using Concurrency for iOS app development, you can use that knowledge directly.

Scheduling

I used Vapor’s Queues for scheduling. Currently, the officially supported driver is QueuesRedisDriver.

You can create a ScheduledJob or an AsyncScheduledJob compliant one and register it to schedule jobs.

As you can see from the name, AsyncScheduledJob supports the Concurrency feature.

For example, this content generation and github update job is written as follows.

struct GenerateAppleDevNewsJob: AsyncScheduledJob {
init() {}

func run(context: QueueContext) async throws {
let client = context.application.client
let content = try await generateMdContent(client: client)
try await updateGitHub(client: client, content: content.content)
}
.
.
.

In the configure (where the app configuration process is written)

let generateAppleDevNews = GenerateAppleDevNewsJob()
app.queues.schedule(generateAppleDevNews)
.weekly()
.on(.sunday)
.at(.noon)
try app.queues.startScheduledJobs()

Getting data by RSS

It was troublesome to parse RSS responses, so I used RSS to JSON Converter online to convert the responses into JSON and used it.

Scraping

Some of the data was not provided as RSS, so I scraped some of them.

I used SwiftSoup as an HTML parser. It is an HTML parser made in Swift, supports Swift Package Manager, and has about 3K stars. In this case, I used it simply to retrieve specific content from a specific page, but it was intuitive and convenient to use.

Conclusion

I thought it would be fun to try it out and I hope to make something in the future.

I hope this will be of some help to you.

Reference

--

--