Thanks! That looks like a good start.
I don't have lots of time right now so please excuse my telegraph style comments below
- I think there are too many top-level types. I think the API could benefit from nesting related types
- why is it
swift-nio-http2-apns
? I think you should drop thehttp2
, I'm sure that if APNS switched to say HTTP/1.1 (unlikely ) you'd then implement that too in this package -
APNSResponse
's API looks more complicated than necessary to me: You setresponse.data
and if that fails,response.error
gets set behind the scenes. I think there should be an initialiserinit<Bytes: Sequence>(bytes: Bytes) throws where Bytes.Element == UInt8
and if the initialisation fails, it would justthrow
- the APNS payload type is called
APSPayload
, is there anN
missing? - API docs would be great. For example there's a
threadID
, I believe that's for conversation threads or something? - why do we need the
APNSNotificationProtocol
protocol? Why don't we just pass the containedaps: APSPayload
? -
APNSRequestEncoder
closes theChannel
if something goes wrong. Usually a reusableChannelHandler
that is a NIO-citizen does not close theChannel
itself. It rather usescontext.fireErrorCaught(error)
through theChannelPipeline
so that the user can choose what to do. In most cases, there's no recovery and the 'application handler' (usually the last handler in a pipeline) will close the connection. But in certain cases the user might be able to handle the error and then we shouldn't just throw away the channel. -
APNSStreamHandler
shouldn't be necessary, you can just useRequestResponseHandler
which should be way more efficient and correct. - please do not
@_exported import
(inExported.swift
), this will break SemVer majorly - do we need the
APNSSigner
protocol? There is only one implementation (DataSigner
). I think we could renameDataSigner
toAPNSSigner
. The parameters don't actually need to beData
, you literally only get their pointer. If you just make theinit(data:)
andsign(digest:)
argumentsUnsafeRawBufferPointer
then you can addData
,ByteBuffer
, andArray<UInt8>
convenience functions - this looks very dangerous:
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || !defined(LIBRESSL_VERSION_NUMBER)
typedef struct ECDSA_SIG_st {
BIGNUM *r;
BIGNUM *s;
} ECDSA_SIG;
#endif
because if defines a type that must match your system's OpenSSL version's definition of that struct. If it's not a perfect match then really bad things will happen.