aster.cloud aster.cloud
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
aster.cloud aster.cloud
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
  • Programming

Announcing SwiftNIO IMAP

  • aster.cloud
  • September 6, 2022
  • 4 minute read

As part of expanding the Swift on Server ecosystem, we’re thrilled to announce the release of a new IMAPv4 parser and encoder, SwiftNIO IMAP.

This package implements:


Partner with aster.cloud
for your next big idea.
Let us know here.



From our partners:

CITI.IO :: Business. Institutions. Society. Global Political Economy.
CYBERPOGO.COM :: For the Arts, Sciences, and Technology.
DADAHACKS.COM :: Parenting For The Rest Of Us.
ZEDISTA.COM :: Entertainment. Sports. Culture. Escape.
TAKUMAKU.COM :: For The Hearth And Home.
ASTER.CLOUD :: From The Cloud And Beyond.
LIWAIWAI.COM :: Intelligence, Inside and Outside.
GLOBALCLOUDPLATFORMS.COM :: For The World's Computing Needs.
FIREGULAMAN.COM :: For The Fire In The Belly Of The Coder.
ASTERCASTER.COM :: Supra Astra. Beyond The Stars.
BARTDAY.COM :: Prosperity For Everyone.

  • Parsing IMAPv4 wire-format to type-safe Swift data structures
  • Encoding these Swift data structures to the IMAPv4 wire format
  • Extensive support for common IMAP extensions
  • High performance
  • Integration with SwiftNIO

Motivation

Email has been a indispensable part of the internet for over 40 years and is a ubiquitous part of many products and services today.

Internet Message Access Protocol (IMAP) is the most widely used open standard to retrieve email messages. It has been around for multiple decades and has evolved substantially over the years through various RFCs.

Correctly parsing and encoding IMAP is notoriously difficult. SwiftNIO IMAP reduces this difficulty by handling many subtle details of encoding and parsing IMAP, making it easier than ever to write rich and powerful email integrations with Swift on server.

This package is focused on parsing and encoding IMAP while also providing some common convenience methods related to core IMAP types. It does not implement any of busines logic related to IMAP.

A Brief Tour

The SwiftNIO IMAP targets RFC 3501, IMAP version 4rev1, and additionally supports extensions from more than 20 RFCs: RFC 2087, 2177, 2221, 2342, 2971, 3348, 3501, 3502, 3516, 3691, 4315, 4467, 4469, 4731, 4959, 5032, 5161, 5182, 5258, 5464, 5819, 6154, 6851, 7162, 7377, 7888, and 8438.

IMAP uses a text-based “human readable” wire format, and SwiftNIO IMAP bridges this to a type-safe world using modern Swift data structures. The protocol is “asymetric”: messages sent from the server follow different patterns that messages sent by the client.

Example Exchange

As a quick example, here’s part of the the exchange listed in RFC 3501 section 8, where lines starting with S: and C: are from the server and client respectively:

S:   * OK IMAP4rev1 Service Ready
C:   a001 login mrc secret
S:   a001 OK LOGIN completed
C:   a002 select inbox
S:   * 18 EXISTS
S:   * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S:   * 2 RECENT
S:   * OK [UNSEEN 17] Message 17 is the first unseen message
S:   * OK [UIDVALIDITY 3857529045] UIDs valid
S:   a002 OK [READ-WRITE] SELECT completed

The first 3 lines would correspond to the following in SwiftNIO IMAP:

<span class="kt">Response</span><span class="o">.</span><span class="nf">untagged</span><span class="p">(</span><span class="o">.</span><span class="nf">conditionalState</span><span class="p">(</span><span class="o">.</span><span class="nf">ok</span><span class="p">(</span><span class="kt">ResponseText</span><span class="p">(</span><span class="nv">text</span><span class="p">:</span> <span class="s">"IMAP4rev1 Service Ready"</span><span class="p">))))</span>
<span class="kt">CommandStreamPart</span><span class="o">.</span><span class="nf">tagged</span><span class="p">(</span><span class="kt">TaggedCommand</span><span class="p">(</span><span class="nv">tag</span><span class="p">:</span> <span class="s">"a001"</span><span class="p">,</span> <span class="nv">command</span><span class="p">:</span> <span class="o">.</span><span class="nf">login</span><span class="p">(</span><span class="nv">username</span><span class="p">:</span> <span class="s">"mrc"</span><span class="p">,</span> <span class="nv">password</span><span class="p">:</span> <span class="s">"secret"</span><span class="p">)))</span>
<span class="kt">Response</span><span class="o">.</span><span class="nf">tagged</span><span class="p">(</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">tag</span><span class="p">:</span> <span class="s">"a001"</span><span class="p">,</span> <span class="nv">state</span><span class="p">:</span> <span class="o">.</span><span class="nf">ok</span><span class="p">(</span><span class="kt">ResponseText</span><span class="p">(</span><span class="nv">text</span><span class="p">:</span> <span class="s">"LOGIN completed"</span><span class="p">))))</span>

Next, up is the SELECT command and its responses, which are more interesting:

<span class="kt">CommandStreamPart</span><span class="o">.</span><span class="nf">tagged</span><span class="p">(</span><span class="kt">TaggedCommand</span><span class="p">(</span><span class="nv">tag</span><span class="p">:</span> <span class="s">"a002"</span><span class="p">,</span> <span class="nv">command</span><span class="p">:</span> <span class="o">.</span><span class="nf">select</span><span class="p">(</span><span class="kt">MailboxName</span><span class="p">(</span><span class="s">"box1"</span><span class="p">),</span> <span class="p">[])))</span>
<span class="kt">Response</span><span class="o">.</span><span class="nf">untagged</span><span class="p">(</span><span class="o">.</span><span class="nf">mailboxData</span><span class="p">(</span><span class="o">.</span><span class="nf">exists</span><span class="p">(</span><span class="mi">18</span><span class="p">)))</span>
<span class="kt">Response</span><span class="o">.</span><span class="nf">untagged</span><span class="p">(</span><span class="o">.</span><span class="nf">mailboxData</span><span class="p">(</span><span class="o">.</span><span class="nf">flags</span><span class="p">([</span><span class="o">.</span><span class="n">answered</span><span class="p">,</span> <span class="o">.</span><span class="n">flagged</span><span class="p">,</span> <span class="o">.</span><span class="n">deleted</span><span class="p">,</span> <span class="o">.</span><span class="n">seen</span><span class="p">,</span> <span class="o">.</span><span class="n">draft</span><span class="p">])))</span>
<span class="kt">Response</span><span class="o">.</span><span class="nf">untagged</span><span class="p">(</span><span class="o">.</span><span class="nf">mailboxData</span><span class="p">(</span><span class="o">.</span><span class="nf">recent</span><span class="p">(</span><span class="mi">2</span><span class="p">)))</span>
<span class="kt">Response</span><span class="o">.</span><span class="nf">untagged</span><span class="p">(</span><span class="o">.</span><span class="nf">conditionalState</span><span class="p">(</span><span class="o">.</span><span class="nf">ok</span><span class="p">(</span><span class="kt">ResponseText</span><span class="p">(</span><span class="nv">code</span><span class="p">:</span> <span class="o">.</span><span class="nf">unseen</span><span class="p">(</span><span class="mi">17</span><span class="p">),</span> <span class="nv">text</span><span class="p">:</span> <span class="s">"Message 17 is the first unseen message"</span><span class="p">))))</span>
<span class="kt">Response</span><span class="o">.</span><span class="nf">untagged</span><span class="p">(</span><span class="o">.</span><span class="nf">conditionalState</span><span class="p">(</span><span class="o">.</span><span class="nf">ok</span><span class="p">(</span><span class="kt">ResponseText</span><span class="p">(</span><span class="nv">code</span><span class="p">:</span> <span class="o">.</span><span class="nf">uidValidity</span><span class="p">(</span><span class="mi">3857529045</span><span class="p">),</span> <span class="nv">text</span><span class="p">:</span> <span class="s">"UIDs valid"</span><span class="p">))))</span>
<span class="kt">Response</span><span class="o">.</span><span class="nf">tagged</span><span class="p">(</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">tag</span><span class="p">:</span> <span class="s">"a002"</span><span class="p">,</span> <span class="nv">state</span><span class="p">:</span> <span class="o">.</span><span class="nf">ok</span><span class="p">(</span><span class="kt">ResponseText</span><span class="p">(</span><span class="nv">code</span><span class="p">:</span> <span class="o">.</span><span class="n">readWrite</span><span class="p">,</span> <span class="nv">text</span><span class="p">:</span> <span class="s">"SELECT completed"</span><span class="p">))))</span>

There’s more going on here than this example shows. But this gives a general idea of how things look and feel.

Read More  Apple Provides Developers With Even More Powerful Technologies To Push The App Experience Forward

Common Values

Some of the very common values used in IMAP are UIDs, message sequence numbers, and mailbox names.

SwiftNIO IMAP has a UID and SequenceNumber type, and related types such as UIDRange, UIDSet, SequenceRange, and SequenceSet. The two set types conform to SetAlgebra. And all of these have convenience methods for common operations.

Mailboxes are identified by a “modified UTF-7” encoded string. The MailboxName and MailboxPath types support decoding and encoding these, while allowing to round-trip wrongly-encoded byte strings sometimes found in the wild.

Transparent Literal Support

SwiftNIO IMAP can transparently encode and decode client messages both with the synchronizing and non-synchronizing literal encodings from the base RFC 3501 and RFC 7888 extensions.

These variations are handled transparently – for both client and server:

RFC 3501 “quoted” strings:

C: A001 LOGIN "FRED FOOBAR" "fat man"
S: A001 OK LOGIN completed

RFC 3501 command continuations:

C: A001 LOGIN {11}
S: + Ready for additional command text
C: FRED FOOBAR {7}
S: + Ready for additional command text
C: fat man
S: A001 OK LOGIN completed

RFC 7888 non-synchronizing literals:

C: A001 LOGIN {11+}
C: FRED FOOBAR {7+}
C: fat man
S: A001 OK LOGIN completed

The so-called LITERAL+ / LITERAL- support can be enabled either using a CAPABILITY response from the server or alternatively by explicitly setting encoding options.

Integration with SwiftNIO

SwiftNIO IMAP provides a pair of ChannelHandler objects that can be integrated into a SwiftNIO ChannelPipeline. This allows sending IMAP commands using NIO Channels.

The two handlers SwiftNIO IMAP provides are IMAPClientHandler and IMAPServerHandler. Each of these can be inserted into the ChannelPipeline. They can then be used to encode and decode messages. For example:

<span class="k">let</span> <span class="nv">group</span> <span class="o">=</span> <span class="kt">MultiThreadedEventLoopGroup</span><span class="p">(</span><span class="nv">numberOfThreads</span><span class="p">:</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">channel</span> <span class="o">=</span> <span class="k">try</span> <span class="k">await</span> <span class="kt">ClientBootstrap</span><span class="p">(</span><span class="n">group</span><span class="p">)</span><span class="o">.</span><span class="n">channelInitializer</span> <span class="p">{</span> <span class="n">channel</span> <span class="k">in</span>
    <span class="n">channel</span><span class="o">.</span><span class="n">pipeline</span><span class="o">.</span><span class="nf">addHandler</span><span class="p">(</span><span class="kt">IMAPClientHandler</span><span class="p">())</span>
<span class="p">}</span><span class="o">.</span><span class="nf">connect</span><span class="p">(</span><span class="nv">host</span><span class="p">:</span> <span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="p">,</span> <span class="nv">port</span><span class="p">:</span> <span class="mi">143</span><span class="p">)</span><span class="o">.</span><span class="nf">get</span><span class="p">()</span>

<span class="k">try</span> <span class="k">await</span> <span class="n">channel</span><span class="o">.</span><span class="nf">writeAndFlush</span><span class="p">(</span><span class="kt">CommandStreamPart</span><span class="o">.</span><span class="nf">tagged</span><span class="p">(</span><span class="kt">TaggedCommand</span><span class="p">(</span><span class="nv">tag</span><span class="p">:</span> <span class="s">"a001"</span><span class="p">,</span> <span class="nv">command</span><span class="p">:</span> <span class="o">.</span><span class="nf">login</span><span class="p">(</span><span class="nv">username</span><span class="p">:</span> <span class="s">"mrc"</span><span class="p">,</span> <span class="nv">password</span><span class="p">:</span> <span class="s">"secret"</span><span class="p">))),</span> <span class="nv">promise</span><span class="p">:</span> <span class="kc">nil</span><span class="p">)</span>

The ChannelHandlers support transparent literals, IMAP capabilities, and all of the rest of the functionality of SwiftNIO IMAP. They’re powerful building blocks for IMAP applications on both the server and client.

Read More  Swift Language Announcements From WWDC22

What’s Next

The version of SwiftNIO IMAP we’re releasing today is still a prototype. We want to solicit feedback from the community.

We’ve done extensive testing of the project’s code and we believe that it’s close to being “production ready”. But we would love to have design discussions on the Swift forums about what is missing, and which bits and pieces could be improved.

Get Involved

Your feedback, experience, and contributions are very welcome!

  • Get started by trying out the SwiftNIO IMAP library on GitHub.
  • Discuss the library, suggest improvements and get help in the Swift forums.
  • Open issues for problems you find.
  • Contribute pull requests to fix any issues.

 

By Daniel Eggert
Source Swift


For enquiries, product placements, sponsorships, and collaborations, connect with us at [email protected]. We'd love to hear from you!

Our humans need coffee too! Your support is highly appreciated, thank you!

aster.cloud

Related Topics
  • Swift
  • SwiftNIO
  • SwiftNIO IMAP
You May Also Like
View Post
  • Architecture
  • Data
  • Engineering
  • People
  • Programming
  • Software Engineering
  • Technology
  • Work & Jobs

Predictions: Top 25 Careers Likely In High Demand In The Future

  • June 6, 2023
View Post
  • Programming
  • Software Engineering
  • Technology

Build a Python App to Alert You When Asteroids Are Close to Earth

  • May 22, 2023
View Post
  • Programming

Illuminating Interactions: Visual State In Jetpack Compose

  • May 20, 2023
View Post
  • Computing
  • Data
  • Programming
  • Software
  • Software Engineering

The Top 10 Data Interchange Or Data Exchange Format Used Today

  • May 11, 2023
View Post
  • Architecture
  • Programming
  • Public Cloud

From Receipts To Riches: Save Money W/ Google Cloud & Supermarket Bills – Part 1

  • May 8, 2023
View Post
  • Programming
  • Public Cloud

3 New Ways To Authorize Users To Your Private Workloads On Cloud Run

  • May 4, 2023
View Post
  • Programming
  • Public Cloud

Buffer HTTP Requests With Cloud Tasks

  • May 4, 2023
View Post
  • Programming
  • Public Cloud
  • Software
  • Software Engineering

Learn About Google Cloud’s Updated Renderer For The Maps SDK For Android

  • May 4, 2023

Stay Connected!
LATEST
  • 1
    Just make it scale: An Aurora DSQL story
    • May 29, 2025
  • 2
    Reliance on US tech providers is making IT leaders skittish
    • May 28, 2025
  • Examine the 4 types of edge computing, with examples
    • May 28, 2025
  • AI and private cloud: 2 lessons from Dell Tech World 2025
    • May 28, 2025
  • 5
    TD Synnex named as UK distributor for Cohesity
    • May 28, 2025
  • Weigh these 6 enterprise advantages of storage as a service
    • May 28, 2025
  • 7
    Broadcom’s ‘harsh’ VMware contracts are costing customers up to 1,500% more
    • May 28, 2025
  • 8
    Pulsant targets partner diversity with new IaaS solution
    • May 23, 2025
  • 9
    Growing AI workloads are causing hybrid cloud headaches
    • May 23, 2025
  • Gemma 3n 10
    Announcing Gemma 3n preview: powerful, efficient, mobile-first AI
    • May 22, 2025
about
Hello World!

We are aster.cloud. We’re created by programmers for programmers.

Our site aims to provide guides, programming tips, reviews, and interesting materials for tech people and those who want to learn in general.

We would like to hear from you.

If you have any feedback, enquiries, or sponsorship request, kindly reach out to us at:

[email protected]
Most Popular
  • 1
    Cloud adoption isn’t all it’s cut out to be as enterprises report growing dissatisfaction
    • May 15, 2025
  • 2
    Hybrid cloud is complicated – Red Hat’s new AI assistant wants to solve that
    • May 20, 2025
  • 3
    Google is getting serious on cloud sovereignty
    • May 22, 2025
  • oracle-ibm 4
    Google Cloud and Philips Collaborate to Drive Consumer Marketing Innovation and Transform Digital Asset Management with AI
    • May 20, 2025
  • notta-ai-header 5
    Notta vs Fireflies: Which AI Transcription Tool Deserves Your Attention in 2025?
    • May 16, 2025
  • /
  • Technology
  • Tools
  • About
  • Contact Us

Input your search keywords and press Enter.