{"id":1681,"url":"https://github.com/noodlewerk/NWPusher","last_synced_at":"2025-08-02T04:32:19.117Z","repository":{"id":4598526,"uuid":"5741345","full_name":"noodlewerk/NWPusher","owner":"noodlewerk","description":"OS X and iOS application and framework to play with the Apple Push Notification service (APNs)","archived":false,"fork":false,"pushed_at":"2021-03-30T07:00:58.000Z","size":2838,"stargazers_count":6312,"open_issues_count":29,"forks_count":676,"subscribers_count":170,"default_branch":"master","last_synced_at":"2025-07-14T18:04:39.605Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/noodlewerk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-09-09T20:23:33.000Z","updated_at":"2025-07-04T02:03:23.000Z","dependencies_parsed_at":"2022-08-06T17:00:57.686Z","dependency_job_id":null,"html_url":"https://github.com/noodlewerk/NWPusher","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/noodlewerk/NWPusher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noodlewerk%2FNWPusher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noodlewerk%2FNWPusher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noodlewerk%2FNWPusher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noodlewerk%2FNWPusher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noodlewerk","download_url":"https://codeload.github.com/noodlewerk/NWPusher/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noodlewerk%2FNWPusher/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334615,"owners_count":24233793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:15:53.183Z","updated_at":"2025-08-02T04:32:18.762Z","avatar_url":"https://github.com/noodlewerk.png","language":"Objective-C","funding_links":[],"categories":["Notifications","Applications","Objective-C","Developer","Tools"],"sub_categories":["Push Notifications","Developers","Other free courses"],"readme":"\u003cimg src=\"icon.png\" alt=\"Pusher Icon\" width=\"72\"/\u003e\n\n\nPusher\n======\n\n*OS X and iOS application and framework to play with the Apple Push Notification service (APNs)*\n\n\u003cimg src=\"Docs/osx1.png\" alt=\"Pusher OS X\" width=\"612\"/\u003e\n\n\nInstallation\n------------\nInstall the Mac app using [Homebrew cask](https://github.com/caskroom/homebrew-cask):\n\n```shell\nbrew cask install pusher\n```\n\nOr download the latest `Pusher.app` binary:\n\n- [Download latest binary](https://github.com/noodlewerk/NWPusher/releases/latest)\n\nAlternatively, you can include NWPusher as a framework, using [CocoaPods](https://cocoapods.org/):\n\n```ruby\npod 'NWPusher', '~\u003e 0.7.0'\n```\n\nor [Carthage](https://github.com/Carthage/Carthage) (iOS 8+ is required to use Cocoa Touch Frameworks)\n\n```\ngithub \"noodlewerk/NWPusher\"\n```\n\nOr simply include the source files you need. NWPusher has a modular architecture and does not have any external dependencies, so use what you like.\n\n\nAbout\n-----\nTesting 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 (\u003c 1 sec) and reliably. However when nothing comes in, it can be very hard to find out why.\n\nThat'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.\n\nPusher 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.\n\n\nFeatures\n--------\nMac OS X application for sending push notifications through the APN service:\n- Takes *certificates and keys* directly from the *keychain*\n- Fully customizable *payload* with *syntax checking*\n- Allows setting *expiration* and *priority*\n- *Stores device tokens* so you don't have to copy-paste them every time\n- Handles *PKCS #12* files (.p12)\n- Automatic configuration for *sandbox*\n- Reports *detailed error messages* returned by APNs\n- Reads from *feedback service*\n\nOS X and iOS framework for sending pushes from your own application:\n- Modular, no dependencies, use what you like\n- Fully documented source code\n- Detailed error handling\n- iOS compatible, so you can also push directly from your iPhone :o\n- Demo applications for both platforms\n\n\nGetting started\n---------------\nBefore 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.\n\nSecond 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.\n\n### Certificate\nLet'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:\n\n1. Log in to [Apple's Dev Center](https://developer.apple.com)\n2. Go to the *Provisioning Portal* or *Certificates, Identifiers \u0026 Profiles*\n3. Go to *Certificates* and create a *Apple Push Notification service SSL*\n4. From here on you will be guided through the certificate generation process.\n\nKeep 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:\n\n\u003cimg src=\"Docs/keychain1.png\" alt=\"Keychain export\" width=\"690\"/\u003e\n\nNB: 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*.\n\nThe push certificate should be exported to a PKCS12 file, which allows you to share these with fellow developers:\n\n\u003cimg src=\"Docs/keychain2.png\" alt=\"PKCS12 file\" width=\"690\"/\u003e\n\n### Device token\nNow 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):\n\n```objective-c\n- (BOOL)application:(UIApplication *)application\n    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {\n        NSLog(@\"Requesting permission for push notifications...\"); // iOS 8\n        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:\n            UIUserNotificationTypeAlert | UIUserNotificationTypeBadge |\n            UIUserNotificationTypeSound categories:nil];\n        [UIApplication.sharedApplication registerUserNotificationSettings:settings];\n    } else {\n        NSLog(@\"Registering device for push notifications...\"); // iOS 7 and earlier\n        [UIApplication.sharedApplication registerForRemoteNotificationTypes:\n            UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |\n            UIRemoteNotificationTypeSound];\n    }\n    return YES;\n}\n\n- (void)application:(UIApplication *)application\n    didRegisterUserNotificationSettings:(UIUserNotificationSettings *)settings\n{\n    NSLog(@\"Registering device for push notifications...\"); // iOS 8\n    [application registerForRemoteNotifications];\n}\n\n- (void)application:(UIApplication *)application\n    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token\n{\n    NSLog(@\"Registration successful, bundle identifier: %@, mode: %@, device token: %@\",\n        [NSBundle.mainBundle bundleIdentifier], [self modeString], token);\n}\n\n- (void)application:(UIApplication *)application\n    didFailToRegisterForRemoteNotificationsWithError:(NSError *)error\n{\n    NSLog(@\"Failed to register: %@\", error);\n}\n\n- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier\n    forRemoteNotification:(NSDictionary *)notification completionHandler:(void(^)())completionHandler\n{\n    NSLog(@\"Received push notification: %@, identifier: %@\", notification, identifier); // iOS 8\n    completionHandler();\n}\n\n- (void)application:(UIApplication *)application\n    didReceiveRemoteNotification:(NSDictionary *)notification\n{\n    NSLog(@\"Received push notification: %@\", notification); // iOS 7 and earlier\n}\n\n- (NSString *)modeString\n{\n#if DEBUG\n    return @\"Development (sandbox)\";\n#else\n    return @\"Production\";\n#endif\n}\n```\n\nNow, when you run the application, the 64 character push string will be logged to the console.\n\n### Push from OS X\nWith 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:\n\n\u003cimg src=\"Docs/osx1.png\" alt=\"Pusher OS X\" width=\"612\"/\u003e\n\nThe 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*.\n\nNow 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.\n\nIf things are not working as expected, then take a look at the *Troubleshooting* section below.\n\n\u003cimg src=\"Docs/osx2.png\" alt=\"Pusher OS X\" width=\"612\"/\u003e\n\n### Push from iOS\nThe 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:\n\n\u003cimg src=\"Docs/ios.png\" alt=\"Pusher iOS\" width=\"414\"/\u003e\n\nIf everything is set up correctly, you only need to *Connect* and *Push*. Then you should receive the `Testing..` push message on the device.\n\nAgain, if things are not working as expected, take a look at the *Troubleshooting* section below or post an issue on GitHub.\n\nConsult Apple's documentation for more info on the APNs architecture: [Apple Push Notification Service](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html)\n\nPushing from code\n-----------------\nPusher 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:\n\n```ruby\npod 'NWPusher', '~\u003e 0.7.0'\n```\n\nCocoaPods also compiles documentation, which can be accessed through [CocoaDocs](http://cocoadocs.org/docsets/NWPusher). Alternatively you can include just the files you need from the `Classes` folder. Make sure you link with `Foundation.framework` and `Security.framework`.\n\nBefore any notification can be sent, you first need to create a connection. When this connection is established, any number of payloads can be sent.\n\n*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.\n\nTo create a connection directly from a PKCS12 (.p12) file:\n\n```objective-c\n    NSURL *url = [NSBundle.mainBundle URLForResource:@\"pusher.p12\" withExtension:nil];\n    NSData *pkcs12 = [NSData dataWithContentsOfURL:url];\n    NSError *error = nil;\n    NWPusher *pusher = [NWPusher connectWithPKCS12Data:pkcs12 password:@\"pa$$word\" error:\u0026error];\n    if (pusher) {\n        NSLog(@\"Connected to APNs\");\n    } else {\n        NSLog(@\"Unable to connect: %@\", error);\n    }\n```\n\nWhen pusher is successfully connected, send a payload to your device:\n\n```objective-c\n    NSString *payload = @\"{\\\"aps\\\":{\\\"alert\\\":\\\"Testing..\\\"}}\";\n    NSString *token = @\"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\";\n    NSError *error = nil;\n    BOOL pushed = [pusher pushPayload:payload token:token identifier:rand() error:\u0026error];\n    if (pushed) {\n        NSLog(@\"Pushed to APNs\");\n    } else {\n        NSLog(@\"Unable to push: %@\", error);\n    }\n```\n\nAfter a second or so, we can take a look to see if the notification was accepted by Apple:\n\n```objective-c\n    NSUInteger identifier = 0;\n    NSError *apnError = nil;\n    NSError *error = nil;\n    BOOL read = [pusher readFailedIdentifier:\u0026identifier apnError:\u0026apnError error:\u0026error];\n    if (read \u0026\u0026 apnError) {\n        NSLog(@\"Notification with identifier %i rejected: %@\", (int)identifier, apnError);\n    } else if (read) {\n        NSLog(@\"Read and none failed\");\n    } else {\n        NSLog(@\"Unable to read: %@\", error);\n    }\n```\n\nAlternatively on OS X you can also use the keychain to obtain the SSL certificate. In that case first collect all certificates:\n\n```objective-c\n    NSError *error = nil;\n    NSArray *certificates = [NWSecTools keychainCertificatesWithError:\u0026error];\n    if (certificates) {\n        NSLog(@\"Loaded %i certificates\", (int)certificates.count);\n    } else {\n        NSLog(@\"Unable to access keychain: %@\", error);\n    }\n```\n\nAfter selecting the right certificate, obtain the identity from the keychain:\n\n```objective-c\n    NSError *error = nil;\n    NWIdentityRef identity = [NWSecTools keychainIdentityWithCertificate:certificate error:\u0026error];\n    if (identity) {\n        NSLog(@\"Loaded identity: %@\", [NWSecTools inspectIdentity:identity]);\n    } else {\n        NSLog(@\"Unable to create identity: %@\", error);\n    }\n```\n\nTake a look at the example project for variations on this approach.\n\nConsult Apple's documentation for more info on the client-server communication: [Provider Communication](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html)\n\nFeedback Service\n----------------\nThe 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.\n\nCommunication with the feedback service can be done with the `NWPushFeedback` class. First connect using one of the `connect` methods:\n\n```objective-c\n    NSURL *url = [NSBundle.mainBundle URLForResource:@\"pusher.p12\" withExtension:nil];\n    NSData *pkcs12 = [NSData dataWithContentsOfURL:url];\n    NSError *error = nil;\n    NWPushFeedback *feedback = [NWPushFeedback connectWithPKCS12Data:pkcs12 password:@\"pa$$word\" error:\u0026error];\n    if (feedback) {\n        NSLog(@\"Connected to feedback service\");\n    } else {\n        NSLog(@\"Unable to connect to feedback service: %@\", error);\n    }\n```\n\nWhen connected read the device token and date of invalidation:\n\n```objective-c\n    NSError *error = nil;\n    NSArray *pairs = [feedback readTokenDatePairsWithMax:100 error:\u0026error];\n    if (pairs) {\n        NSLog(@\"Read token-date pairs: %@\", pairs);\n    } else {\n        NSLog(@\"Unable to read feedback: %@\", error);\n    }\n```\n\nApple closes the connection after the last device token is read.\n\nPushing to macOS\n---------------\n\nOn 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.\n\nThe 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:\n\n- Use the `application:didRegisterForRemoteNotificationsWithDeviceToken:` to receive the device token and forward it to your server.\n- Use the `application:didFailToRegisterForRemoteNotificationsWithError:` to respond to errors.\n\nNote: 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.\n\nThe 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.\n\n```objective-c\n    - (void)applicationDidFinishLaunching:(NSNotification *)notification {\n        // Configure the user interactions first.\n        [self configureUserInteractions];\n\n        [NSApp registerForRemoteNotificationTypes:(NSRemoteNotificationTypeAlert | NSRemoteNotificationTypeSound)];\n    }\n```\n\n```objective-c\n    - (void)application:(NSApplication *)application\n        didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {\n        // Forward the token to your server.\n        [self forwardTokenToServer:deviceToken];\n    }\n```\n\n```objective-c\n    - (void)application:(NSApplication *)application\n        didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {\n        NSLog(@\"Remote notification support is unavailable due to error: %@\", error);\n        [self disableRemoteNotificationFeatures];\n    }\n```\n\n\nCertificate and key files\n-------------------------\nPusher 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.\n\n*Inspect PKCS12:*\n\n    openssl pkcs12 -in pusher.p12\n\nwhere the output should be something like:\n\n    ...\n    friendlyName: Apple Development/Production IOS/Mac Push Services: \u003cyour-bundle-identifier\u003e\n    localKeyID: \u003ckey-id\u003e\n    ...\n    -----BEGIN CERTIFICATE-----\n    ...\n    friendlyName: \u003cprivate-key-used-for-generating-above-certificate\u003e\n    localKeyID: \u003csame-key-id\u003e\n    ...\n    -----BEGIN PRIVATE KEY-----\n    ...\n\nMake sure your build matches the `Development/Production`, `iOS/Mac`, and bundle identifier.\n\n*Inspect PKCS12 structure:*\n\n    openssl pkcs12 -in pusher.p12 -info -noout\n\n*Inspect PEM:*\n\n    openssl rsa -in pusher.pem -noout -check\n    openssl rsa -in pusher.pem -pubout\n    openssl x509 -in pusher.pem -noout -pubkey\n\n*PKCS12 to PEM:*\n\n    openssl pkcs12 -in pusher.p12 -out pusher.pem -clcerts -aes256\n\nAlternatively you can use the command below, which does *not* encrypt the private key (not recommended):\n\n    openssl pkcs12 -in pusher.p12 -out pusher.pem -nodes -clcerts\n\n*PEM to PKCS12:*\n\n    openssl pkcs12 -export -in pusher.pem -out pusher.p12\n\nConsult the OpenSSL documentation for more details: [OpenSSL Documents - pkcs12](https://www.openssl.org/docs/apps/pkcs12.html)\n\nTroubleshooting\n---------------\nApple'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.\n\nSome tips on what to look out for:\n\n- 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.\n\n- 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.\n\nIf it fails to connect then check:\n\n- 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`.\n\n- Is the certificate properly loaded? Try initializing an identity using `[NWSecTools identityWithPKCS12Data:data password:password error:\u0026error]` or `[NWSecTools keychainIdentityWithCertificate:certificate error:\u0026error]`.\n\n- 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.\n\n- Can you connect with the push servers? Try `[NWPusher connectWithIdentity:identity error:\u0026error]` or `[NWPusher connectWithPKCS12Data:pkcs12 password:password error:\u0026error]`.\n\n- 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.\n\nIf nothing is delivered to the device then check:\n\n- 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.\n\n- 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.\n\n- 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:\u0026error]` and `[pusher readFailedIdentifier:\u0026identifier apnError:\u0026apnError error:\u0026error]` should return `YES`, but wait a second between pushing and reading. Also try to connect to the feedback service to read feedback.\n\nConsult Apple's documentation for more troubleshooting tips: [Troubleshooting Push Notifications](https://developer.apple.com/library/mac/technotes/tn2265/_index.html)\n\nBuild with Xcode\n----------------\nThe 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`:\n\n    xcodebuild -project NWPusher.xcodeproj -target PusherMac -configuration Release clean install\n\nAfter a successful build, `Pusher.app` can be found in the `build` folder of the project.\n\nDocumentation\n-------------\nDocumentation generated and installed using *appledoc* by running from the project root:\n\n    appledoc .\n\nSee the [appledoc documentation](http://gentlebytes.com/appledoc/) for more info.\n\nLicense\n-------\nPusher is licensed under the terms of the BSD 2-Clause License, see the included LICENSE file.\n\n\nAuthors\n-------\n- [Noodlewerk](http://www.noodlewerk.com/)\n- [Leonard van Driel](http://www.leonardvandriel.nl/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoodlewerk%2FNWPusher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoodlewerk%2FNWPusher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoodlewerk%2FNWPusher/lists"}