GithubHelp home page GithubHelp logo

noodlewerk / nwpusher Goto Github PK

View Code? Open in Web Editor NEW
6.3K 172.0 680.0 2.77 MB

OS X and iOS application and framework to play with the Apple Push Notification service (APNs)

License: BSD 2-Clause "Simplified" License

Objective-C 89.04% C 10.53% Ruby 0.43%

nwpusher's Introduction

Pusher Icon

Pusher

OS X and iOS application and framework to play with the Apple Push Notification service (APNs)

Pusher OS X

Installation

Install the Mac app using Homebrew cask:

brew cask install pusher

Or download the latest Pusher.app binary:

Alternatively, you can include NWPusher as a framework, using CocoaPods:

pod 'NWPusher', '~> 0.7.0'

or Carthage (iOS 8+ is required to use Cocoa Touch Frameworks)

github "noodlewerk/NWPusher"

Or simply include the source files you need. NWPusher has a modular architecture and does not have any external dependencies, so use what you like.

About

Testing push notifications for your iOS or Mac app can be a pain. You might consider setting up your own server or use one of the many push webservices online. Either way it's a lot of work to get all these systems connected properly. When it is all working properly, push notifications come in fast (< 1 sec) and reliably. However when nothing comes in, it can be very hard to find out why.

That's why I made Pusher. It is a Mac and iPhone app for sending push notifications directly to the Apple Push Notification Service. No need to set up a server or create an account online. You only need the SSL certificate and a device token to start pushing directly from your Mac, or even from an iPhone! Pusher has detailed error reporting and logs, which are very helpful with verifying your setup.

Pusher comes with a small framework for both OS X and iOS. It provides various tools for sending notifications programmatically. On OS X it can use the keychain to retrieve push certificates and keys. Pusher can also be used without keychain, using a PKCS #12 file. If you want to get a better understanding of how push notifications work, then this framework is a good place to start and play around.

Features

Mac OS X application for sending push notifications through the APN service:

  • Takes certificates and keys directly from the keychain
  • Fully customizable payload with syntax checking
  • Allows setting expiration and priority
  • Stores device tokens so you don't have to copy-paste them every time
  • Handles PKCS #12 files (.p12)
  • Automatic configuration for sandbox
  • Reports detailed error messages returned by APNs
  • Reads from feedback service

OS X and iOS framework for sending pushes from your own application:

  • Modular, no dependencies, use what you like
  • Fully documented source code
  • Detailed error handling
  • iOS compatible, so you can also push directly from your iPhone :o
  • Demo applications for both platforms

Getting started

Before you can start sending push notification payloads, there are a few hurdles to take. First you'll need to obtain the Apple Push Services SSL Certificate of the app you want to send notifications to. This certificate is used by Pusher to set up the SSL connection through which the payloads will be sent to Apple.

Second you'll need the device token of the device you want to send your payload to. Every device has its own unique token that can only be obtained from within the app. It's a bit complicated, but in the end it all comes down to just a few clicks on Apple's Dev Center website, some gray hairs, and a bit of patience.

Certificate

Let's start with the SSL certificate. The goal is to get both the certificate and the private key into your OS X keychain. If someone else already generated this certificate, you'll need to ask for exporting these into a PKCS12 file. If there is no certificate generated yet, you can generate the certificate and the private key in the following steps:

  1. Log in to Apple's Dev Center
  2. Go to the Provisioning Portal or Certificates, Identifiers & Profiles
  3. Go to Certificates and create a Apple Push Notification service SSL
  4. From here on you will be guided through the certificate generation process.

Keep in mind that you will eventually be downloading a certificate, which you will need to install in your keychain together with the private key. This should look something like this:

Keychain export

NB: There is Development and Production certificates, which should (generally) correspond to respectively DEBUG and RELEASE versions of your app. Make sure you get the right one, check Development (sandbox) or Production, iOS or Mac, and the bundle identifier.

The push certificate should be exported to a PKCS12 file, which allows you to share these with fellow developers:

PKCS12 file

Device token

Now you need to obtain a device token, which is a 64 character hex string (256 bits). This should be done from within the iOS app you're going to push to. Add the following lines to the application delegate (Xcode 6 required):

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        NSLog(@"Requesting permission for push notifications..."); // iOS 8
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:
            UIUserNotificationTypeAlert | UIUserNotificationTypeBadge |
            UIUserNotificationTypeSound categories:nil];
        [UIApplication.sharedApplication registerUserNotificationSettings:settings];
    } else {
        NSLog(@"Registering device for push notifications..."); // iOS 7 and earlier
        [UIApplication.sharedApplication registerForRemoteNotificationTypes:
            UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
            UIRemoteNotificationTypeSound];
    }
    return YES;
}

- (void)application:(UIApplication *)application
    didRegisterUserNotificationSettings:(UIUserNotificationSettings *)settings
{
    NSLog(@"Registering device for push notifications..."); // iOS 8
    [application registerForRemoteNotifications];
}

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token
{
    NSLog(@"Registration successful, bundle identifier: %@, mode: %@, device token: %@",
        [NSBundle.mainBundle bundleIdentifier], [self modeString], token);
}

- (void)application:(UIApplication *)application
    didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"Failed to register: %@", error);
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier
    forRemoteNotification:(NSDictionary *)notification completionHandler:(void(^)())completionHandler
{
    NSLog(@"Received push notification: %@, identifier: %@", notification, identifier); // iOS 8
    completionHandler();
}

- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)notification
{
    NSLog(@"Received push notification: %@", notification); // iOS 7 and earlier
}

- (NSString *)modeString
{
#if DEBUG
    return @"Development (sandbox)";
#else
    return @"Production";
#endif
}

Now, when you run the application, the 64 character push string will be logged to the console.

Push from OS X

With the SSL certificate and private key in the keychain and the device token on the pasteboard, you're ready to send some push notifications. Let's start by sending a notification using the Pusher app for Mac OS X. Open the Pusher Xcode project and run the PusherMac target:

Pusher OS X

The combo box at the top lists the available SSL certificates in the keychain. Select the certificate you want to use and paste the device token of the device you're pushing to. The text field below shows the JSON formatted payload text that you're sending. Read more about this format in the Apple documentation under Apple Push Notification Service.

Now before you press Push, make sure the application you're sending to is in the background, e.g. by pressing the home button. This way you're sure the app is not going to interfere with the message, yet. Press push, wait a few seconds, and see the notification coming in.

If things are not working as expected, then take a look at the Troubleshooting section below.

Pusher OS X

Push from iOS

The ultimate experience is of course pushing from an iPhone to an iPhone, directly. This can be done with the Pusher iOS app. Before you run the PusherTouch target, make sure to include the certificate, private key, and device token inside the app. Take the PKCS12 file that you exported earlier and include it in the PusherTouch bundle. Then go to NWAppDelegate.m in the Touch folder and configure pkcs12FileName, pkcs12Password, and deviceToken. Now run the PusherTouch target:

Pusher iOS

If everything is set up correctly, you only need to Connect and Push. Then you should receive the Testing.. push message on the device.

Again, if things are not working as expected, take a look at the Troubleshooting section below or post an issue on GitHub.

Consult Apple's documentation for more info on the APNs architecture: Apple Push Notification Service

Pushing from code

Pusher can also be used as a framework to send notifications programmatically. The included Xcode project provides examples for both OS X and iOS. The easiest way to include NWPusher is through CocoaPods:

pod 'NWPusher', '~> 0.7.0'

CocoaPods also compiles documentation, which can be accessed through CocoaDocs. Alternatively you can include just the files you need from the Classes folder. Make sure you link with Foundation.framework and Security.framework.

Before any notification can be sent, you first need to create a connection. When this connection is established, any number of payloads can be sent.

Note that Apple doesn't like it when you create a connection for every push. Therefore be careful to reuse a connection as much as possible in order to prevent Apple from blocking.

To create a connection directly from a PKCS12 (.p12) file:

    NSURL *url = [NSBundle.mainBundle URLForResource:@"pusher.p12" withExtension:nil];
    NSData *pkcs12 = [NSData dataWithContentsOfURL:url];
    NSError *error = nil;
    NWPusher *pusher = [NWPusher connectWithPKCS12Data:pkcs12 password:@"pa$$word" error:&error];
    if (pusher) {
        NSLog(@"Connected to APNs");
    } else {
        NSLog(@"Unable to connect: %@", error);
    }

When pusher is successfully connected, send a payload to your device:

    NSString *payload = @"{\"aps\":{\"alert\":\"Testing..\"}}";
    NSString *token = @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
    NSError *error = nil;
    BOOL pushed = [pusher pushPayload:payload token:token identifier:rand() error:&error];
    if (pushed) {
        NSLog(@"Pushed to APNs");
    } else {
        NSLog(@"Unable to push: %@", error);
    }

After a second or so, we can take a look to see if the notification was accepted by Apple:

    NSUInteger identifier = 0;
    NSError *apnError = nil;
    NSError *error = nil;
    BOOL read = [pusher readFailedIdentifier:&identifier apnError:&apnError error:&error];
    if (read && apnError) {
        NSLog(@"Notification with identifier %i rejected: %@", (int)identifier, apnError);
    } else if (read) {
        NSLog(@"Read and none failed");
    } else {
        NSLog(@"Unable to read: %@", error);
    }

Alternatively on OS X you can also use the keychain to obtain the SSL certificate. In that case first collect all certificates:

    NSError *error = nil;
    NSArray *certificates = [NWSecTools keychainCertificatesWithError:&error];
    if (certificates) {
        NSLog(@"Loaded %i certificates", (int)certificates.count);
    } else {
        NSLog(@"Unable to access keychain: %@", error);
    }

After selecting the right certificate, obtain the identity from the keychain:

    NSError *error = nil;
    NWIdentityRef identity = [NWSecTools keychainIdentityWithCertificate:certificate error:&error];
    if (identity) {
        NSLog(@"Loaded identity: %@", [NWSecTools inspectIdentity:identity]);
    } else {
        NSLog(@"Unable to create identity: %@", error);
    }

Take a look at the example project for variations on this approach.

Consult Apple's documentation for more info on the client-server communication: Provider Communication

Feedback Service

The feedback service is part of the Apple Push Notification service. The feedback service is basically a list containing device tokens that became invalid. Apple recommends that you read from the feedback service once every 24 hours, and no longer send notifications to listed devices. Note that this can be used to find out who removed your app from their device.

Communication with the feedback service can be done with the NWPushFeedback class. First connect using one of the connect methods:

    NSURL *url = [NSBundle.mainBundle URLForResource:@"pusher.p12" withExtension:nil];
    NSData *pkcs12 = [NSData dataWithContentsOfURL:url];
    NSError *error = nil;
    NWPushFeedback *feedback = [NWPushFeedback connectWithPKCS12Data:pkcs12 password:@"pa$$word" error:&error];
    if (feedback) {
        NSLog(@"Connected to feedback service");
    } else {
        NSLog(@"Unable to connect to feedback service: %@", error);
    }

When connected read the device token and date of invalidation:

    NSError *error = nil;
    NSArray *pairs = [feedback readTokenDatePairsWithMax:100 error:&error];
    if (pairs) {
        NSLog(@"Read token-date pairs: %@", pairs);
    } else {
        NSLog(@"Unable to read feedback: %@", error);
    }

Apple closes the connection after the last device token is read.

Pushing to macOS

On macOS, you obtain a device token for your app by calling the registerForRemoteNotificationTypes: method of the NSApplication object. It is recommended that you call this method at launch time as part of your normal startup sequence. The first time your app calls this method, the app object requests the token from APNs. After the initial call, the app object contacts APNs only when the device token changes; otherwise, it returns the existing token quickly.

The app object notifies its delegate asynchronously upon the successful or unsuccessful retrieval of the device token. You use these delegate callbacks to process the device token or to handle any errors that arose. You must implement the following delegate methods to track whether registration was successful:

  • Use the application:didRegisterForRemoteNotificationsWithDeviceToken: to receive the device token and forward it to your server.
  • Use the application:didFailToRegisterForRemoteNotificationsWithError: to respond to errors.

Note: If the device token changes while your app is running, the app object calls the appropriate delegate method again to notify you of the change.

The app delegate calls the registerForRemoteNotificationTypes: method as part of its regular launch-time setup, passing along the types of interactions that you intend to use. Upon receiving the device token, the application:didRegisterForRemoteNotificationsWithDeviceToken: method forwards it to the app’s associated server using a custom method. If an error occurs during registration, the app temporarily disables any features related to remote notifications. Those features are re-enabled when a valid device token is received.

    - (void)applicationDidFinishLaunching:(NSNotification *)notification {
        // Configure the user interactions first.
        [self configureUserInteractions];

        [NSApp registerForRemoteNotificationTypes:(NSRemoteNotificationTypeAlert | NSRemoteNotificationTypeSound)];
    }
    - (void)application:(NSApplication *)application
        didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        // Forward the token to your server.
        [self forwardTokenToServer:deviceToken];
    }
    - (void)application:(NSApplication *)application
        didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
        NSLog(@"Remote notification support is unavailable due to error: %@", error);
        [self disableRemoteNotificationFeatures];
    }

Certificate and key files

Pusher reads certificate and key data from PKCS12 files. This is a binary format that bundles both X.509 certificates and a private key in one file. Conversion from other file formats to and from PKCS12 is provided by the OpenSSL CLI.

Inspect PKCS12:

openssl pkcs12 -in pusher.p12

where the output should be something like:

...
friendlyName: Apple Development/Production IOS/Mac Push Services: <your-bundle-identifier>
localKeyID: <key-id>
...
-----BEGIN CERTIFICATE-----
...
friendlyName: <private-key-used-for-generating-above-certificate>
localKeyID: <same-key-id>
...
-----BEGIN PRIVATE KEY-----
...

Make sure your build matches the Development/Production, iOS/Mac, and bundle identifier.

Inspect PKCS12 structure:

openssl pkcs12 -in pusher.p12 -info -noout

Inspect PEM:

openssl rsa -in pusher.pem -noout -check
openssl rsa -in pusher.pem -pubout
openssl x509 -in pusher.pem -noout -pubkey

PKCS12 to PEM:

openssl pkcs12 -in pusher.p12 -out pusher.pem -clcerts -aes256

Alternatively you can use the command below, which does not encrypt the private key (not recommended):

openssl pkcs12 -in pusher.p12 -out pusher.pem -nodes -clcerts

PEM to PKCS12:

openssl pkcs12 -export -in pusher.pem -out pusher.p12

Consult the OpenSSL documentation for more details: OpenSSL Documents - pkcs12

Troubleshooting

Apple's Push Notification Service is not very forgiving in nature. If things are done in the wrong order or data is formatted incorrectly the service will refuse to deliver any notification, but generally provides few clues about went wrong and how to fix it. In the worst case, it simply disconnects without even notifying the client.

Some tips on what to look out for:

  • A device token is unique to both the device, the developer's certificate, and to whether the app was built with a production or development (sandbox) certificate. Therefore make sure that the push certificate matches the app's provisioning profile exactly. This doesn't mean the tokens are always different; device tokens can be the same for different bundle identifiers.

  • There are two channels through which Apple responds to pushed notifications: the notification connection and the feedback connection. Both operate asynchronously, so for example after the second push has been sent, we might get a response to the first push, saying it has an invalid payload. Use a new identifier for every notification so these responses can be linked to the right notification.

If it fails to connect then check:

  • Are the certificates and keys in order? Use the OpenSSL commands listed above to inspect the certificate. See if there is one push certificate and key present. Also make sure you're online, try ping www.apple.com.

  • Is the certificate properly loaded? Try initializing an identity using [NWSecTools identityWithPKCS12Data:data password:password error:&error] or [NWSecTools keychainIdentityWithCertificate:certificate error:&error].

  • Are you using the right identity? Use [NWSecTools inspectIdentity:identity] to inspect the identity instance. In general NWSecTools can be helpful for inspecting certificates, identities and the keychain.

  • Can you connect with the push servers? Try [NWPusher connectWithIdentity:identity error:&error] or [NWPusher connectWithPKCS12Data:pkcs12 password:password error:&error].

  • Pusher connects on port 2195 with hosts gateway.push.apple.com and gateway.sandbox.push.apple.com, and on port 2196 with hosts feedback.push.apple.com and feedback.sandbox.push.apple.com. Make sure your firewall is configured to allow these connections.

If nothing is delivered to the device then check:

  • Is the device online? Is it able to receive push notifications from other services? Try to get pushes from other apps, for example a messenger. Many wireless connections work visibly fine, but do not deliver push notifications. Try to switch to another wifi or cellular network.

  • Are you pushing to the right device token? This token should be returned by the OS of the receiving device, in the callback -application: didRegisterForRemoteNotificationsWithDeviceToken:. The push certificate should match the provisioning profile of the app, check Development or Production, iOS or Mac, and the bundle identifier. Make sure the receiving app is closed, so it cannot interfere with the delivery.

  • Does the push call succeed? Isn't there any negative response from the push server or feedback server? Both [pusher pushPayload:payload token:token identifier:rand() error:&error] and [pusher readFailedIdentifier:&identifier apnError:&apnError error:&error] should return YES, but wait a second between pushing and reading. Also try to connect to the feedback service to read feedback.

Consult Apple's documentation for more troubleshooting tips: Troubleshooting Push Notifications

Build with Xcode

The source comes with an Xcode project file that should take care of building the OS X and iOS demo applications. Alternatively you can also build Pusher.app from the commandline with xcodebuild:

xcodebuild -project NWPusher.xcodeproj -target PusherMac -configuration Release clean install

After a successful build, Pusher.app can be found in the build folder of the project.

Documentation

Documentation generated and installed using appledoc by running from the project root:

appledoc .

See the appledoc documentation for more info.

License

Pusher is licensed under the terms of the BSD 2-Clause License, see the included LICENSE file.

Authors

nwpusher's People

Contributors

arix avatar clementpadovani avatar danielfontes avatar readmecritic avatar zats avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nwpusher's Issues

VOIP push setup. Notification error: APN invalid token

Hello

I just got pusher working using a Apple Push Notification service SSL certificate.

My problem is that when i change the Apple Push Notification service SSL certificate to a VoIP Services Certificate in pushed by importing the .p12 i get a `Notification error: APN invalid token.

The app is built from xCode using a development provisioning profile.

Thanks for any help.

Support for Pass Type ID

It appears that NWPusher does not support Pass Type ID certificates.

These certificates are used for sending push notifications wallet passes. You use the same certificate for signing a certificate and for sending pushes.

How could we get support for this added in?

Thanks for your consideration! I really appreciate it.

Device token size is variable length.

I've been trying to add push notification to my app this morning and I'm running into an issue with the device token. In the Readme it says that the device token size is 64 characters and there is code to handle this. However in this documentation it says

"Important: APNs device tokens are of variable length. Do not hardcode their size."

When I run this code:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
{
    ...

    // PUSH notification
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .sound, .badge]) {
        granted, error in
        if granted == true {
            Logger.add("Notifications granted")
        }
        if let error = error {
            Logger.add("Error getting notifications grant \(error)")
        }
    }
    UIApplication.shared.registerForRemoteNotifications()

    return true
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let str1 : String = String(describing: deviceToken)
    let str2 = String(data: deviceToken, encoding: String.Encoding.utf32)
    let str3 : String = deviceToken.base64EncodedString()
    print("original token \(deviceToken)")
    print("str1 \(str1)")
    print("str2 \(str2)")
    print("str3 \(str3)")
}

The results are this:
2016-08-23 12:14:15.550336 Ree SE[1137:587543] Notifications granted
original token 32 bytes
str1 32 bytes
str2 nil
str3 FkIgF1jqz8X0mMX4IG1YnpyjeTBwgoGsODqHs0Cag/s=

The last one's the only one that looks like it might be a token but it's not 64 characters. I tried various encoding types other than utf32 but nothing came up looking right at all. Is there something I'm doing wrong in getting the token? What about the discrepancy in the documentation?

Mike

hi~thank you for this tool ,but I have a question

I saw a function like this
`- (NWEnvironment)preferredEnvironmentForCertificate:(NWCertificateRef)certificate
{
NWEnvironmentOptions environmentOptions = [NWSecTools environmentOptionsForCertificate:certificate];

return (environmentOptions & NWEnvironmentOptionSandbox) ? NWEnvironmentSandbox : NWEnvironmentProduction;

}`

I don't understand the return value.
there is only one situation the function will return NWEnvironmentProduction,when environmentOptions is NWEnvironmentOptionNone
I want to know what situation NWEnvironmentProduction or NWEnvironmentAuto will be used

General cert name

Apple recently changed their APNS handling and new certificates are named "Apple Push Services" instead of "Apple Production IOS Push Services". When I now try to import one of these Pusher refuses to import them.

NWSSLConnection fails to read and write

The error code "errSSLWouldBlock" in the methods
- (BOOL)write:(NSData *)data length:(NSUInteger *)length error:(NSError *__autoreleasing *)error;
and
- (BOOL)read:(NSMutableData *)data length:(NSUInteger *)length error:(NSError *__autoreleasing *)error;
is handled as if the data was successfully written / read.

If this code is used for sending lots of notifications only the first few would make it into the socket send buffer until the kernel would report "EAGAIN" or "EWOULDBLOCK".
If the socket is marked as nonblocking the kernel is allowed to report "EAGAIN" or "EWOULDBLOCK" for any reason but most of the time it is because of a full buffer.
SecureTransport is reporting this by setting "errSSLWouldBlock" after the SSLWrite() attempt.

The same is true for reading.

A quick fix would be to just return NO on this error or to loop until all bytes are in the buffer.
A full solution would be to implement a write buffer:

  • When the user wants to send data, append it to buffer.
  • Delete the amount of bytes written by SSLWrite() from the beginning of the buffer.
  • When SSLWrite() dose not manage to write all the data or returns errSSLWouldBlock try again later by monitoring the socket for the next write event with GCD, kqueue, poll() or select().

There are great all in one solutions on git that could be used as a drop-in solution for NWSSLConnection (GCDAsyncSocket for example).

Failed to connect to APNS

Pusher was working just fine until a few days back. Now, it does not seem to be connecting to APNS and fails with the error log mentioned below.

Connecting to APN... (app_bundle_id sandbox)
Unable to connect: Socket connecting failed (-1)

I'm on MacOS Sierra 10.12.4 and I have tried connecting using both the sandbox and the production certificates, but it fails with the same error in both the cases.

Any ideas as to what might be happening?

Cannot connecting to APNS

Hi,

I don't know if it is related to the Keynote of today but it seems that we have connecting issues :

Connecting
Failure

Version 0.7.0 (15)

Thanks

Installing NWPusher on OS X 10.9.5

Hi, I have installed NWPusher both with "brew" and "binary" as you say but it was not possible to run it after installing. Is it necessary to have some OSX version?

Killer icon! Literally...!

Sorry about spamming your issue list, but I just had to commend you on the app - and the app icon, espesh!

Completely worthwhile, well done :)

  • A

Change icon?

This is a great app, very helpful. The icon is kind of disturbing; would you consider changing it to something more neutral?

Library function to push same payload on multiple tokens

Hello there,
Your library is working flawlessly and I am missing the following:

Could you add something like that?

-(void)pushPayloadString:(NSString *)payload tokens:(NSArray *)tokens expires:(NSDate *)expires block:(void(^)(NWPusherResult response))block;

to push the same payload on multiple tokens.

Regards,
Nikos

Simulate PKPushPayload

Hello,
Great app and library. Currently push notification get sent to the

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

I want to capture them in

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type

with PKPushRegistry type PKPushTypeVoIP

Any tips?

Thanks.

can use HTTP/2 APNs?

i created Apple Push Notification service SSL (Sandbox & Production),i used the pusher.app. selected universal SSL certificate, the sandbox&production already received remote push.
NWPusher support the HTTP/2 APNs?

App is not working any more

Hello,
App is not working any more.
I have tried other tools to which is available on online too. But same they also failed to connect.

Thanks

Add payload saving

Would it be possible to add saved payloads? I'm generally working on more than one project at a time and so switching between items to push to requires a completely different payload. Would be much easier if I could select a payload associated with a certificate/keychain and have that prepopulated.

Notifications to ALL devices

Is there a way to send the notification to ALL devices?
So far I only managed to send to one device using the Token
but if I try without the token I can't send it.

Unable to connect: SSL handshake connection closed via error

Hi

I saw other threads that had this error with an error code but I am getting this error with no error code.

I have a valid push certificate and whenever I try to select it from the keychain or import the .p12 I get this error.

Any ideas?

Update:

When I check the status object in NWSSLConnection I get -9806

Update 2: Oddly if I uncheck the Should Use Sandbox it connects to the production. However the second I try to push in that environment I get the error:

Unable to read: Read connection closed

Update 3: It looks like messed up security settings on the company Wifi. When I pair with my phone and use that data, I connect just fine.

Porting to Swift 3.0

Any intention to port it to Swift 3.0 ? There are several issues related to the error management that would be easier to cope with if you poor the library.

I have also another problem. Unexpectedly, sometimes it refuses
to work with the error "Invalid Device Token", but I'm sure it is valid, because it works with other testing tools. Thanks

No push certificates found

When using NWPusher, I'm not able to import the Apple Push Services certificate I've just created for Adhoc distribution.

Steps to reproduce:

1 - Create a new App ID;
2 - Create a Production Certificate for Push Notifications;
3 - Create the AdHoc provisioning profile.
4 - Export the Production Certificate (Apple Push Services) into a .p12 file.
5 - Open it with NWPusher.

The result is:

Unable to import p12 file: no push certificates found.

Rich Content Push Notifications not going through

Push notifications with "mutable-content":0 are delivered right away, but I'm trying to test to see if rich push notifications are working with my app via the Pusher desktop app with this payload and they don't seem to be delivered to my iPhone.

Is there some reason why Pusher would not support this? Or maybe it's Apple that's failing to deliver, but as far as I can tell the payload is correct.

{
  "aps": {
    "alert": {
      "title": "Realtime Custom Push Notifications",
      "subtitle": "Now with iOS 10 support!",
      "body": "Add multimedia content to your notifications"
    },
    "sound": "default",
    "badge": 1,
    "mutable-content": 1,
    "category": "realtime",
    "data": {
      "attachment-url": "https://framework.realtime.co/blog/img/ios10-video.mp4"
    }
  }
}

Prompting for password for p12 when there is none

I created my certificates using PEM which creates p12 files without passwords. If I use the p12 on others services it works fine, but Pusher seems to ask for a password, and if I leave it blank i get this error "Unable to read p12 file: PKCS12 data wrong password" and it doesn't show up in the list of certificates.

APNS Auth key .p8 support

This is more a suggestion/question. You can tag it appropriately.

Does this support the new .p8 file as certificate - APNs Auth Key?

Command line support

Has any work been done to make NWPusher support the command line?

What I'd like to do is support sending a push from a command line build script, something like:
$> NWPusher --token <1234afaf - owen> --cert --body {"aps":"message..." ...}

And have a push notification be sent to the respective device.

It'd be helpful to plug that into build scripts, cron jobs, etc.

If that sounds useful to anyone else I'll try to work on a pull request with support.

Rich text issues

There are some issues when copy pasting JSON from other editors since rich text gets copied over.

Notification error: APN invalid token

Hello, when I try to use APN Production SSL Certificate to do Push Notifications it failed and got "Notification error: APN invalid token". But if I use Development SSL Certificate it work fine!!

Did any one know what is the problem in it?
thanks a lot!!

SSL handshake failed (-9829)

Hello !

Thanks for NWPusher, it really nice for my work !

But today, i get this error "SSL handshake failed (-9829)", and my app crash.

Problem is, not alway crash when app run. Sometime it error, sometime it OK

This my code (swift)
error

This error
screen shot 2016-09-18 at 8 53 44 am

Sorry my bad English !

Thanks for support !

Regard !

SSL Handshake failure for production certificate.

Hi, am using your test app for IOS trying to get push notifications to work. I have included the correct p12 file and password. But when I try to connect it gives me the error: Unable to connect: Unable to perform SSL handshake

Weird thing is I also tried on the Mac app and it works just perfect on there so am thinking it isn't my certificate. Any clues to why this is failing?

Unable to connect (-9810)

Hello, i have this error :
Unable to connect: SSL handshake failed (-9810)
i check sandbox environment and unchecked but I still have this problem.
How can i resolved it ?

Any Plans to support Apple Authentication Key (.p8) files?

Hi there,

since a while Apple supports authentication keys that never expire and can be re-configured after creation. Some services already support this. Any plans my favourite push testing utility supports this too in near future?

Example to retrieve TOKEN from push notification is wrong

  • (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token
    {
    NSString *string = [[[token stringByReplacingOccurrencesOfString:@" " withString:@""] substringWithRange:NSMakeRange(1, 64)]uppercaseString];
    NSLog(@"Device token: %@", string);
    }

token is NSData type.
token stringByReplacingOccurrencesOfString raises an error.

I use this:

  • (void)application:(UIApplication_)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData_)deviceToken
    {
    NSString *token = [self hexString:deviceToken];
    NSLog(@"Remote APN token is: %@", token);
    }
  • (NSString_)hexString:(NSData_)devicetoken
    {
    unichar* hexChars = (unichar_)malloc(sizeof(unichar) * (devicetoken.length_2));
    unsigned char* bytes = (unsigned char_)devicetoken.bytes;
    for (NSUInteger i = 0; i < devicetoken.length; i++) {
    unichar c = bytes[i] / 16;
    if (c < 10) c += '0';
    else c += 'A' - 10;
    hexChars[i_2] = c;
    c = bytes[i] % 16;
    if (c < 10) c += '0';
    else c += 'A' - 10;
    hexChars[i_2+1] = c;
    }
    NSString_ retVal = [[NSString alloc] initWithCharactersNoCopy:hexChars
    length:devicetoken.length*2
    freeWhenDone:YES];
    return retVal;
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.