Antumbra
iOS macOS swift SwiftUI APNS tool Estimated reading time: 6 minutesTesting push notifications sometimes can be a problematic process. In one of the previous posts I covered base practices and how we can do that.
Another moment that was covered in that post - I show my dev tool for testing: pushHandle
. It was a raw tool with limited functionality (only p8 key support) and poor UI.
Some time passed and I faced again the need to test push notifications. For this time, I completely redesign the app and add a ton of new functionality:
- Auth with p8 key
- Auth with p12 cert
- Auth with keychain
- Custom push payload
- Payload JSON validation
- Predefined payloads
- Full customization of push
- Build in hints
- Multiply sessions
- Session persistants
- History with detailed info
- Inspection of request with option to use curl for p8 auth
- Rich failure description
- Light/Dark mode
- Written in Swift
All this is combined into the new tool - Antumbra - OS X app for sending pushes with Apple Push Notification service (APNs) over HTTP/2 API.
If u wondering what is the word Antumbra means - check this wiki page for more.
the app
I decided to make a universal free and open-source tool that covers push notifications test purposes from different prospects.
The idea was taken originally from Pusher app - a great tool, that is not supported anymore. After checking alternatives I found PushHero app - a good one, but u need to pay 15$ for that.
The overall app UI looks like this
I spend some free time in the evening creating this tool.
The good source of information was original Apple posts about push work. I strongly recommend this to u if u want to learn to push in details. unusually detailed posts.
During creating this tool, I also learn a few new stuff that I haven’t work before. The most interesting are:
- work with Security framework and keychain
- an inner structure of certificates
- details of file protection system (sandbox) on macOS
The most interesting one - is working with API from Security
framework.
Knowledge about keychains and certificates is needed to be able to accomplish a part of the functionality that uses installed certificates for APNS from an inside keychain.
keychain and certificates
I won’t cover all the theory about certificates and keychains here, but here is the link for doc related to this part.
The interesting for our purposes part - is to get the list of certificates and fetch needed details from each entity, later use that to sign our APNS request.
certificate
The certificate is represented via SecCertificate
. We then can ispect the certificate for various values - name, issuer, validity date, etc.
For purpose of this app, I created an object that represents a certificate - KeychainCertificate
:
import Security
struct KeychainCertificate: Equatable, Hashable {
let certificate: SecCertificate
}
Yep, that’s easy :). SecCertificate
contains all the info we need later. We can check the SecIdentity
header for convenient methods of getting specific info from the certificate.
The certificate can provide us with different values. For example, to get SecIdentity
:
We also can use the SecCertificateOIDs
header to fetch some specific data from a key-value collection of data provided by the certificate. Part of the data extracted from the certificate:
What we need - this is a date. To get this, we can do the following:
I think there must be some type existing to cast a value not to
NSDictionary.self
but to it… but, didn’t find it.
All the next - u can extend this type as u wish, adding more and more values via computed properties.
full code for `KeychainCertificate`
fetch certificates
The first part is done. Now we must somehow fetch all the certificates from the keychain.
To do so, we can check doc and see, that there is a function SecItemCopyMatching(::) that can help us.
credentials
And last but not least part - use certificate as a credential in URLSession
.
A sign can be done via URLCredential
- the entity that is used by a delegate of URLSession
and able to provide authentication info for it.
Using these 3 step and crafting some UI, I got this:
conclusion
Always try to improve the process. This gives u at least 2 benefits - u learn something, u improve something.
Check out my tool here. Feel free to open pr for improving it or open issue for reporting a problem.
resources
Share on: