16 Commits

Author SHA1 Message Date
Leo Vandriel c91a8e08c4 Merge pull request #62 from ClementPadovani/hotfix/make_plain_text_great_again
Removed all notions of rich text and disabled “smart” additions
2018-01-26 12:52:31 -08:00
Clément Padovani 6a8a48dfd9 Removed all notions of rich text and disabled “smart” additions 2017-12-30 20:50:11 +01:00
Leo 5b46a5c6de add certificate type to description 2017-04-26 11:06:32 -07:00
Leo a854649e09 bump version 2017-04-25 15:27:20 -07:00
Leo 36de866909 update changelog 2017-04-25 15:27:14 -07:00
Leo Vandriel 9371147fd1 Add support for new certificate type (passes) 2017-04-25 13:59:17 -07:00
Leonard van Driel 60288f8454 Merge pull request #49 from ClementPadovani/hotfix/rich_text_copy_paste
Disabled rich text.
2017-04-04 10:07:37 -07:00
Clément Padovani 5b4a2e5e94 Disabled rich text. 2017-04-01 13:07:33 +02:00
Leo Vandriel 2d1b534f4d fix app name in menu, issue #47 2017-03-20 11:43:42 -07:00
Leo Vandriel 26d42ca585 add docs pushing to macOS (issue by dylib) 2017-03-13 15:22:49 -07:00
Leo Vandriel 900b107dc0 bump version 2017-01-16 12:53:03 -08:00
Leo Vandriel 65738cad39 add support for ssl handshake internal error 2017-01-16 12:43:47 -08:00
Leo Vandriel ff5768048c add detection for p12 without password 2017-01-16 12:24:29 -08:00
Leonard van Driel 9b6770afe1 Merge pull request #35 from JanC/fix_umbrella_header
Fixed missing umbrella header
2016-12-04 11:29:20 -08:00
Jan Chaloupecky b4c0e1e72b Fixed missing umbrella header 2016-11-09 16:32:56 +01:00
Leo Vandriel 5bab81d099 add firewall info in readme 2016-09-26 09:16:50 -07:00
13 changed files with 151 additions and 54 deletions
+14
View File
@@ -3,6 +3,20 @@ Change Log
### master (unreleased)
* add certificate type to description
### 0.7.5 (2017-04-25)
* Add support for new certificate type (passes)
* Fix rich text (#49)
* Fix app name (#47)
* Update docs pushing to macOS
### 0.7.4 (2017-01-16)
* Add support for handshake error (internal error)
* Add detection of p12 without password
### 0.7.3 (2016-09-19)
* Add support for Watch Kit certificates (DanielFontes)
+1
View File
@@ -143,6 +143,7 @@ OSStatus NWSSLWrite(SSLConnectionRef connection, const void *data, size_t *lengt
case errSSLPeerCertExpired: return [NWErrorUtil noWithErrorCode:kNWErrorSSLHandshakePeerCertExpired error:error];
case errSSLPeerCertRevoked: return [NWErrorUtil noWithErrorCode:kNWErrorSSLHandshakePeerCertRevoked error:error];
case errSSLPeerCertUnknown: return [NWErrorUtil noWithErrorCode:kNWErrorSSLHandshakePeerCertUnknown error:error];
case errSSLInternal: return [NWErrorUtil noWithErrorCode:kNWErrorSSLHandshakeInternalError error:error];
#if !TARGET_OS_IPHONE
case errSecInDarkWake: return [NWErrorUtil noWithErrorCode:kNWErrorSSLInDarkWake error:error];
#endif
+3
View File
@@ -43,6 +43,9 @@
/** @name Inspection */
/** Extracts the type and summary string. */
+ (NWCertType)typeWithCertificate:(NWCertificateRef)certificate summary:(NSString **)summary;
/** Extracts the summary string. */
+ (NSString *)summaryWithCertificate:(NWCertificateRef)certificate;
+6 -26
View File
@@ -7,31 +7,6 @@
#import "NWSecTools.h"
/** Types of push certificates. */
typedef NS_ENUM(NSInteger, NWCertType) {
/** None. */
kNWCertTypeNone = 0,
/** iOS Development. */
kNWCertTypeIOSDevelopment = 1,
/** iOS Production. */
kNWCertTypeIOSProduction = 2,
/** OS X Development. */
kNWCertTypeMacDevelopment = 3,
/** OS X Production. */
kNWCertTypeMacProduction = 4,
/** Simplified Certificate Handling. */
kNWCertTypeSimplified = 5,
/** Web Push Production. */
kNWCertTypeWebProduction = 6,
/** VoIP Services. */
kNWCertTypeVoIPServices = 7,
/** WatchKit Services. */
kNWCertTypeWatchKitServices = 8,
/** Unknown. */
kNWCertTypeUnknown = 9,
};
@implementation NWSecTools
#pragma mark - Initialization
@@ -139,6 +114,7 @@ typedef NS_ENUM(NSInteger, NWCertType) {
case kNWCertTypeWebProduction:
case kNWCertTypeVoIPServices:
case kNWCertTypeWatchKitServices:
case kNWCertTypePasses:
return NWEnvironmentOptionAny;
case kNWCertTypeNone:
case kNWCertTypeUnknown:
@@ -158,6 +134,7 @@ typedef NS_ENUM(NSInteger, NWCertType) {
case kNWCertTypeWebProduction:
case kNWCertTypeVoIPServices:
case kNWCertTypeWatchKitServices:
case kNWCertTypePasses:
return YES;
case kNWCertTypeNone:
case kNWCertTypeUnknown:
@@ -177,6 +154,7 @@ typedef NS_ENUM(NSInteger, NWCertType) {
case kNWCertTypeWebProduction: return @"Website Push ID: ";
case kNWCertTypeVoIPServices: return @"VoIP Services: ";
case kNWCertTypeWatchKitServices: return @"WatchKit Services: ";
case kNWCertTypePasses: return @"Pass Type ID: ";
case kNWCertTypeNone:
case kNWCertTypeUnknown:
break;
@@ -249,7 +227,7 @@ typedef NS_ENUM(NSInteger, NWCertType) {
+ (NSArray *)allIdentitiesWithPKCS12Data:(NSData *)data password:(NSString *)password error:(NSError *__autoreleasing *)error
{
NSDictionary *options = @{(__bridge id)kSecImportExportPassphrase: password};
NSDictionary *options = password ? @{(__bridge id)kSecImportExportPassphrase: password} : @{};
CFArrayRef items = NULL;
OSStatus status = data ? SecPKCS12Import((__bridge CFDataRef)data, (__bridge CFDictionaryRef)options, &items) : errSecParam;
NSArray *dicts = CFBridgingRelease(items);
@@ -259,6 +237,7 @@ typedef NS_ENUM(NSInteger, NWCertType) {
case errSecAuthFailed: return [NWErrorUtil nilWithErrorCode:kNWErrorPKCS12AuthFailed error:error];
#if !TARGET_OS_IPHONE
case errSecPkcs12VerifyFailure: return [NWErrorUtil nilWithErrorCode:kNWErrorPKCS12Password error:error];
case errSecPassphraseRequired: return [NWErrorUtil nilWithErrorCode:kNWErrorPKCS12PasswordRequired error:error];
#endif
}
return [NWErrorUtil nilWithErrorCode:kNWErrorPKCS12Import reason:status error:error];
@@ -345,6 +324,7 @@ typedef NS_ENUM(NSInteger, NWCertType) {
case kNWCertTypeWebProduction:
case kNWCertTypeVoIPServices:
case kNWCertTypeWatchKitServices:
case kNWCertTypePasses:
case kNWCertTypeNone:
case kNWCertTypeUnknown:
break;
+31
View File
@@ -17,6 +17,32 @@ typedef NS_ENUM(NSInteger, NWNotificationType) {
kNWNotificationType2 = 2,
};
/** Types of push certificates. */
typedef NS_ENUM(NSInteger, NWCertType) {
/** None. */
kNWCertTypeNone = 0,
/** iOS Development. */
kNWCertTypeIOSDevelopment = 1,
/** iOS Production. */
kNWCertTypeIOSProduction = 2,
/** OS X Development. */
kNWCertTypeMacDevelopment = 3,
/** OS X Production. */
kNWCertTypeMacProduction = 4,
/** Simplified Certificate Handling. */
kNWCertTypeSimplified = 5,
/** Web Push Production. */
kNWCertTypeWebProduction = 6,
/** VoIP Services. */
kNWCertTypeVoIPServices = 7,
/** WatchKit Services. */
kNWCertTypeWatchKitServices = 8,
/** Pass Type ID. */
kNWCertTypePasses = 9,
/** Unknown. */
kNWCertTypeUnknown = 10,
};
/** An ARC-friendly replacement of SecIdentityRef. */
typedef id NWIdentityRef;
@@ -111,6 +137,8 @@ typedef NS_ENUM(NSInteger, NWError) {
kNWErrorSSLHandshakePeerCertRevoked = -230,
/** SSL handshake certificate unknown. */
kNWErrorSSLHandshakePeerCertUnknown = -233,
/** SSL handshake internal error. */
kNWErrorSSLHandshakeInternalError = -234,
/** SSL handshake in dark wake. */
kNWErrorSSLInDarkWake = -231,
/** SSL handshake connection closed via error. */
@@ -151,6 +179,8 @@ typedef NS_ENUM(NSInteger, NWError) {
kNWErrorPKCS12AuthFailed = -312,
/** PKCS12 data wrong password. */
kNWErrorPKCS12Password = -313,
/** PKCS12 data password required. */
kNWErrorPKCS12PasswordRequired = -314,
/** PKCS12 data contains no identities. */
kNWErrorPKCS12NoItems = -307,
/** PKCS12 data contains multiple identities. */
@@ -189,6 +219,7 @@ extern NSString * const NWErrorReasonCodeKey;
/** Returns string for given environment, for logging purposes */
NSString * descriptionForEnvironentOptions(NWEnvironmentOptions environmentOptions);
NSString * descriptionForEnvironent(NWEnvironment environment);
NSString * descriptionForCertType(NWCertType type);
@interface NWErrorUtil : NSObject
+20
View File
@@ -31,6 +31,24 @@ NSString * descriptionForEnvironent(NWEnvironment environment)
return nil;
}
NSString * descriptionForCertType(NWCertType type)
{
switch (type) {
case kNWCertTypeNone: return @"none";
case kNWCertTypeIOSDevelopment:
case kNWCertTypeIOSProduction: return @"iOS";
case kNWCertTypeMacDevelopment:
case kNWCertTypeMacProduction: return @"macOS";
case kNWCertTypeSimplified: return @"All";
case kNWCertTypeWebProduction: return @"Website";
case kNWCertTypeVoIPServices: return @"VoIP";
case kNWCertTypeWatchKitServices: return @"WatchKit";
case kNWCertTypePasses: return @"Pass";
case kNWCertTypeUnknown: return @"unknown";
}
return nil;
}
@implementation NWErrorUtil
+ (NSString *)stringWithCode:(NWError)code
@@ -80,6 +98,7 @@ NSString * descriptionForEnvironent(NWEnvironment environment)
case kNWErrorSSLHandshakePeerCertExpired : return @"SSL handshake certificate expired";
case kNWErrorSSLHandshakePeerCertRevoked : return @"SSL handshake certificate revoked";
case kNWErrorSSLHandshakePeerCertUnknown : return @"SSL handshake certificate unknown";
case kNWErrorSSLHandshakeInternalError : return @"SSL handshake internal error";
case kNWErrorSSLInDarkWake : return @"SSL handshake in dark wake";
case kNWErrorSSLHandshakeClosedAbort : return @"SSL handshake connection closed via error";
case kNWErrorSSLHandshakeTimeout : return @"SSL handshake timeout";
@@ -102,6 +121,7 @@ NSString * descriptionForEnvironent(NWEnvironment environment)
case kNWErrorPKCS12Decode : return @"PKCS12 data cannot be read or is malformed";
case kNWErrorPKCS12AuthFailed : return @"PKCS12 data password incorrect";
case kNWErrorPKCS12Password : return @"PKCS12 data wrong password";
case kNWErrorPKCS12PasswordRequired : return @"PKCS12 data password required";
case kNWErrorPKCS12NoItems : return @"PKCS12 data contains no identities";
case kNWErrorPKCS12MultipleItems : return @"PKCS12 data contains multiple identities";
+19 -19
View File
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner">
@@ -63,7 +64,7 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit NewApplication" keyEquivalent="q" id="4sb-4s-VLi">
<menuItem title="Pusher" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
</connections>
@@ -158,7 +159,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="600" height="300"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
<value key="minSize" type="size" width="500" height="200"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="600" height="300"/>
@@ -232,7 +233,7 @@
</popUpButtonCell>
</popUpButton>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EnU-aP-5PD">
<rect key="frame" x="461" y="177" width="121" height="24"/>
<rect key="frame" x="456" y="177" width="126" height="24"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="Olm-G5-Man">
<font key="font" metaFont="system"/>
<segments>
@@ -268,11 +269,11 @@
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q6j-iu-9I9">
<rect key="frame" x="20" y="45" width="560" height="130"/>
<clipView key="contentView" id="e4e-ov-ymY">
<rect key="frame" x="1" y="1" width="558" height="150"/>
<rect key="frame" x="1" y="1" width="558" height="128"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView importsGraphics="NO" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" usesFontPanel="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="ad5-lb-L5u">
<rect key="frame" x="0.0" y="0.0" width="558" height="150"/>
<textView importsGraphics="NO" richText="NO" verticallyResizable="YES" findStyle="panel" allowsCharacterPickerTouchBarItem="NO" allowsUndo="YES" allowsNonContiguousLayout="YES" textCompletion="NO" id="ad5-lb-L5u">
<rect key="frame" x="0.0" y="0.0" width="558" height="128"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="558" height="128"/>
@@ -286,8 +287,9 @@
</fragment>
</attributedString>
<color key="insertionPointColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="558" height="128"/>
<size key="maxSize" width="573" height="10000000"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
<connections>
<outlet property="delegate" destination="kaW-YJ-UA5" id="bUh-Oq-w5B"/>
</connections>
@@ -300,7 +302,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="sbz-Qw-fOe">
<rect key="frame" x="543" y="1" width="16" height="150"/>
<rect key="frame" x="543" y="1" width="16" height="128"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
@@ -318,18 +320,16 @@
<scrollView hidden="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z4n-XE-cfI">
<rect key="frame" x="20" y="45" width="560" height="130"/>
<clipView key="contentView" id="uaF-sl-etn">
<rect key="frame" x="1" y="1" width="558" height="150"/>
<rect key="frame" x="1" y="1" width="558" height="128"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView importsGraphics="NO" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" usesFontPanel="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="pi6-RR-ayT">
<rect key="frame" x="0.0" y="0.0" width="558" height="150"/>
<textView importsGraphics="NO" richText="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="pi6-RR-ayT">
<rect key="frame" x="0.0" y="0.0" width="558" height="128"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="558" height="128"/>
<size key="maxSize" width="573" height="10000000"/>
<color key="insertionPointColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="558" height="128"/>
<size key="maxSize" width="573" height="10000000"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
@@ -339,12 +339,12 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="pny-Of-exT">
<rect key="frame" x="543" y="1" width="16" height="150"/>
<rect key="frame" x="543" y="1" width="16" height="128"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<button translatesAutoresizingMaskIntoConstraints="NO" id="hU6-Ym-KR3">
<rect key="frame" x="18" y="235" width="228" height="18"/>
<rect key="frame" x="18" y="235" width="223" height="18"/>
<buttonCell key="cell" type="check" title="Should use sandbox environment" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="ros-Zj-bni">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
+8 -3
View File
@@ -170,11 +170,13 @@
NWCertificateRef certificate = pair[0];
BOOL hasIdentity = (pair[1] != NSNull.null);
NWEnvironmentOptions environmentOptions = [NWSecTools environmentOptionsForCertificate:certificate];
NSString *summary = [NWSecTools summaryWithCertificate:certificate];
NSString *summary = nil;
NWCertType certType = [NWSecTools typeWithCertificate:certificate summary:&summary];
NSString *type = descriptionForCertType(certType);
NSDate *date = [NWSecTools expirationWithCertificate:certificate];
NSString *expire = [NSString stringWithFormat:@" [%@]", date ? [formatter stringFromDate:date] : @"expired"];
// summary = @"com.example.app";
[_certificatePopup addItemWithTitle:[NSString stringWithFormat:@"%@%@ (%@)%@%@", hasIdentity ? @"imported: " : @"", summary, descriptionForEnvironentOptions(environmentOptions), expire, suffix]];
[_certificatePopup addItemWithTitle:[NSString stringWithFormat:@"%@%@ (%@ %@)%@%@", hasIdentity ? @"imported: " : @"", summary, type, descriptionForEnvironentOptions(environmentOptions), expire, suffix]];
[suffix appendString:@" "];
}
[_certificatePopup addItemWithTitle:@"Import PKCS #12 file (.p12)..."];
@@ -206,6 +208,9 @@
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSArray *ids = [NWSecTools identitiesWithPKCS12Data:data password:password error:&error];
if (!ids && password.length == 0 && error.code == kNWErrorPKCS12Password) {
ids = [NWSecTools identitiesWithPKCS12Data:data password:nil error:&error];
}
if (!ids) {
NWLogWarn(@"Unable to read p12 file: %@", error.localizedDescription);
return;
@@ -405,7 +410,7 @@
if (read) {
if (!failed) NWLogInfo(@"Payload has been pushed");
} else {
NWLogWarn(@"Unable to read failed: %@", error.localizedDescription);
NWLogWarn(@"Unable to read: %@", error.localizedDescription);
}
[_hub trimIdentifiers];
});
+2 -2
View File
@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.7.3</string>
<string>0.7.5</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>17</string>
<string>19</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'NWPusher'
s.version = '0.7.3'
s.version = '0.7.5'
s.summary = 'OS X and iOS application and framework to play with the Apple Push Notification service (APNs).'
s.homepage = 'https://github.com/noodlewerk/NWPusher'
s.license = { :type => 'BSD', :file => 'LICENSE.txt' }
+1
View File
@@ -20,3 +20,4 @@ FOUNDATION_EXPORT const unsigned char PusherKit_iOSVersionString[];
#import <PusherKit/NWPusher.h>
#import <PusherKit/NWSSLConnection.h>
#import <PusherKit/NWSecTools.h>
#import <PusherKit/NWPushFeedback.h>
+43 -1
View File
@@ -234,7 +234,7 @@ After a second or so, we can take a look to see if the notification was accepted
} else if (read) {
NSLog(@"Read and none failed");
} else {
NSLog(@"Unable to read failed: %@", error);
NSLog(@"Unable to read: %@", error);
}
```
@@ -298,6 +298,46 @@ When connected read the device token and date of invalidation:
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 apps 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.
```objective-c
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
// Configure the user interactions first.
[self configureUserInteractions];
[NSApp registerForRemoteNotificationTypes:(NSRemoteNotificationTypeAlert | NSRemoteNotificationTypeSound)];
}
```
```objective-c
- (void)application:(NSApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Forward the token to your server.
[self forwardTokenToServer:deviceToken];
}
```
```objective-c
- (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.
@@ -366,6 +406,8 @@ If it fails to connect then check:
- 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.
+2 -2
View File
@@ -32,11 +32,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.7.3</string>
<string>0.7.5</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>17</string>
<string>19</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIPrerenderedIcon</key>