コンテンツにスキップ

初期化

アプリの起動時に以下の手順でSDKの初期化処理を行います。

手順

  1. SDK実行キーを設定
  2. delegateの設定
  3. OSに対してプッシュ通知受信の許可をリクエスト
  4. デバイストークンを登録

import

import RichFlyer
#import <RichFlyer/RichFlyer.h>

SDK実行キーの設定

// Class RFApp
static func setServiceKey(serviceKey: String, appGroupId: String, sandbox: Bool)
// Class RFApp
+ setServiceKey:appGroupId:sandbox:
パラメータ 内容
serviceKey 管理サイトで発行されたSDK実行キー
SDK実行キーの取得方法
appGroupId AppGroupsのGroup ID
sandbox 通知の配信種別。
YES:Developmentプロビジョニングを適用する場合
NO:Distributionプロビジョニングを使用している場合

delegateの設定

// Class RFApp
static func setRFNotficationDelegate(delegate: RFNotificationDelegate)
// Class RFApp
+ setRFNotificationDelegate:
パラメータ 内容
delegate RFNotificationDelegateを実装しているクラスのオブジェクト

RFNotificationDelegate

public protocol RFNotificationDelegate {

    // アプリがフォアグラウンドにある場合ときにプッシュ通知を受信
    func willPresentNotification(_ center: UNUserNotificationCenter,
                                    willPresent notification: UNNotification,
                                    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Swift.Void)

    // 通知センターからアプリを起動した
    func didReceiveNotification(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Swift.Void)

    // アプリ起動時表示が閉じられた
    func dismissedContentDisplay(_ action: RFAction?, content: RFContent?) -> Swift.Void  
}
@protocol RFNotificationDelegate <NSObject>
    @optional

    // アプリがフォアグラウンドにある場合ときにプッシュ通知を受信
    - (void)willPresentNotificationWithCenter:(UNUserNotificationCenter *)center
                                notification:(UNNotification *)notification
                        withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler;

    // 通知センターからアプリを起動した
    - (void)didReceiveNotificationWithCenter:(UNUserNotificationCenter *)center
                                    response:(UNNotificationResponse *)response
                                        withCompletionHandler:(void (^)(void))completionHandler;

    // アプリ起動時表示が閉じられた
    - (void)dismissedContentDisplay:(RFAction*)action content:(RFContent*)content;
@end

OSに対してプッシュ通知受信の許可をリクエスト

// Class RFApp
static func requestAuthorization(application: UIApplication, applicationDelegate: UIApplicationDelegate, options: [RFAuthorizationOptions] = [.badge, .sound, .alert, .carPlay])
// Class RFApp
+ requestAuthorizationWithOptions:applicationDelegate:options:
パラメータ 内容
application UIApplicationオブジェクト
applicationDelegate UIApplicationDelegateを実装しているクラスのオブジェクト
options 通知表示のオプション(バッジ、通知の表示、サウンド、カープレイ)
カープレイはiOS10以上で利用可能

通知表示のオプション

public enum RFAuthorizationOptions {
    case badge    // バッジを表示する
    case sound    // サウンドを鳴らす
    case alert    // 受信時に通知を表示
    case carPlay  // カープレイ
}
typedef NS_OPTIONS(NSUInteger, RFAuthorizationOptions) {
RFAuthorizationOptionNone    = 0,          
    RFAuthorizationOptionBadge   = (1 << 0), // バッジを表示する
    RFAuthorizationOptionSound   = (1 << 1), // サウンドを鳴らす
    RFAuthorizationOptionAlert   = (1 << 2), // 受信時に通知を表示
    RFAuthorizationOptionCarPlay = (1 << 3), // カープレイ
};

デバイストークンを登録

// Class RFApp
static func registDevice(deviceToken: Data, completion: @escaping (_ result: RFResult) -> Void)
// Class RFApp
+ registDevice:completion:
パラメータ 内容
deviceToken OSから取得したデバイストークン
completion 処理完了時に呼び出されるハンドラ。結果オブジェクト(RFResult)が渡される。

結果オブジェクト

public struct RFResult {
    public let result: Bool    // 結果
    public let message: String // エラーメッセージ
    public let code: Int       // エラーコード
}
@interface RFResult : NSObject

@property (readonly) BOOL result;                            // 結果
@property (readonly, nonatomic, nullable) NSString* message; // エラーメッセージ
@property (readonly) NSInteger code;                         // エラーコード

@end

エラーコード

エラーコード 内容 予想される原因
401 認証失敗 認証トークンが不正か、期限切れの可能性があります。
アプリの再起動または requestAuthorization を呼ぶことで解消する可能性があります。
404 サービス不明 管理サイトで取得したSDK実行キーが指定されていない可能性があります。
SDK実行キーの確認方法
600 通信エラー RichFlyerサーバへの接続に失敗しています。通信環境の悪化等が考えられます。
601 デバイストークン不明 OSから発行されるデバイストークンがRichFlyer SDKに渡されていないか失われた可能性があります。
アプリの再起動または requestAuthorization を呼ぶことで解消する可能性があります。
602 認証トークン不明 デバイストークンの登録に失敗している可能性があります。
アプリの再起動または requestAuthorization を呼ぶことで解消する可能性があります。
603 認証トークン不明 デバイストークンの登録に失敗している可能性があります。
アプリの再起動または requestAuthorization を呼ぶことで解消する可能性があります。
604 SDK実行キー不明 SDK実行キーが指定されていない可能性があります。

iOS SDK27について

iOS SDK27からはUISceneの実装が必須となり、画面(Window)の生成・管理はAppDelegateではなくSceneDelegateで行う仕様となりました。
SDK実行キーの設定・delegateの設定・デバイストークンの登録処理はこれまで通りAppDelegateで行いますが、OSに対する通知受信の許可リクエスト(requestAuthorization)は画面生成後に呼び出す必要があるため、SceneDelegate側で呼び出す実装に変更してください。
具体的な実装例はこちらを参照してください。

実装例

Swift

import UserNotifications
import RichFlyer

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // 管理サイトで発行されたSDK実行キーを設定
        RFApp.setServiceKey(serviceKey: "1234567890",
            appGroupId: "group.jp.co.infocity.richflyer",
            sandbox: false)

        //通知のDelegate設定
        RFApp.setRFNotficationDelegate(delegate: self)

        //OSに対してプッシュ通知受信の許可をリクエスト                                       
        RFApp.requestAuthorization(application: UIApplication.shared, applicationDelegate: self)

        // 自分で通知受信時のOptionを設定する場合
        //RFApp.requestAuthorization(application: UIApplication.shared, applicationDelegate: self, options: [.alert, .badge, .sound])

        return true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        //デバイストークンを登録
        RFApp.registDevice(deviceToken: deviceToken, completion: { (result: RFResult) in
            if (!result.result) {
                // 失敗
                print(result.message + "(code:\(result.code))")
            }
        })

    }
}

extension AppDelegate: RFNotificationDelegate {
    func dismissedContentDisplay(_ action: RFAction?, content: RFContent?) {
    }

    func willPresentNotification(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    }

    func didReceiveNotification(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
    }
}

Objective-C

#import "AppDelegate.h"
#import <RichFlyer/RichFlyer.h>

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 管理サイトで発行されたSDK実行キーを設定
    [RFApp setServiceKey:@"1234567890" appGroupId:@"group.jp.co.infocity.richflyer" sandbox:NO];

    // delegateの設定
    [RFApp setRFNotificationDelegate:self];

    // OSにプッシュ通知の受信許可をリクエスト
    [RFApp requestAuthorization:[UIApplication sharedApplication]
                                applicationDelegate:self];

    // 自分で通知受信時のOptionを設定する場合
    //[RFAppDelegate requestAuthorization:[UIApplication sharedApplication]                                             
    //                                         options:RFAuthorizationOptionAlert|RFAuthorizationOptionBadge|RFAuthorizationOptionSound
    //                             applicationDelegate:self];

    return YES;
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    //デバイストークンを登録
    [RFApp registDevice:deviceToken completion:^(RFResult* result){
        if (!result.result) {
            // 失敗
            NSLog(@"%@(code:%ld)", result.message, (long)result.code);
        }
    }];
}

#pragma mark - RFNotificationDelegate

- (void)didReceiveNotificationWithCenter:(UNUserNotificationCenter *)center response:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
}

- (void)willPresentNotificationWithCenter:(UNUserNotificationCenter *)center notification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
}

- (void)dismissedContentDisplay:(RFAction *)action content:(RFContent*)content {
}

実装例(iOS SDK27〜 UIScene対応の場合)

iOS SDK27からはUISceneの実装が必須となったため、画面(Window)の生成はSceneDelegateで行います。
SDK実行キーの設定・delegateの設定・デバイストークンの登録・RFNotificationDelegateの実装はAppDelegateのままで問題ありませんが、requestAuthorizationは画面生成後に呼び出す必要があるため、SceneDelegateのscene(_:willConnectTo:options:)(Objective-Cではscene:willConnectToSession:options:)内で呼び出します。

Swift

AppDelegate.swift

import UserNotifications
import RichFlyer

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 管理サイトで発行されたSDK実行キーを設定
        RFApp.setServiceKey(serviceKey: "1234567890",
            appGroupId: "group.jp.co.infocity.richflyer",
            sandbox: false)

        //通知のDelegate設定
        RFApp.setRFNotficationDelegate(delegate: self)

        return true
    }

    // UISceneの設定(iOS SDK27より必須)
    func application(_ application: UIApplication,
                      configurationForConnecting connectingSceneSession: UISceneSession,
                      options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        //デバイストークンを登録
        RFApp.registDevice(deviceToken: deviceToken, completion: { (result: RFResult) in
            if (!result.result) {
                // 失敗
                print(result.message + "(code:\(result.code))")
            }
        })

    }
}

extension AppDelegate: RFNotificationDelegate {
    func dismissedContentDisplay(_ action: RFAction?, content: RFContent?) {
    }

    func willPresentNotification(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    }

    func didReceiveNotification(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
    }
}

SceneDelegate.swift

import UIKit
import RichFlyer

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }

        // 画面(Window)の生成
        let window = UIWindow(windowScene: windowScene)
        // window.rootViewController = ...
        window.makeKeyAndVisible()
        self.window = window

        //OSに対してプッシュ通知受信の許可をリクエスト
        RFApp.requestAuthorization(application: UIApplication.shared, applicationDelegate: UIApplication.shared.delegate!)

        // 自分で通知受信時のOptionを設定する場合
        //RFApp.requestAuthorization(application: UIApplication.shared, applicationDelegate: UIApplication.shared.delegate!, options: [.alert, .badge, .sound])
    }
}
Objective-C

AppDelegate.h

#import <UIKit/UIKit.h>
#import <RichFlyer/RichFlyer.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, RFNotificationDelegate>

@end

AppDelegate.m

#import "AppDelegate.h"
#import <RichFlyer/RichFlyer.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 管理サイトで発行されたSDK実行キーを設定
    [RFApp setServiceKey:@"1234567890" appGroupId:@"group.jp.co.infocity.richflyer" sandbox:NO];

    // delegateの設定
    [RFApp setRFNotificationDelegate:self];

    return YES;
}

// UISceneの設定(iOS SDK27より必須)
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    //デバイストークンを登録
    [RFApp registDevice:deviceToken completion:^(RFResult* result){
        if (!result.result) {
            // 失敗
            NSLog(@"%@(code:%ld)", result.message, (long)result.code);
        }
    }];
}

#pragma mark - RFNotificationDelegate

- (void)didReceiveNotificationWithCenter:(UNUserNotificationCenter *)center response:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
}

- (void)willPresentNotificationWithCenter:(UNUserNotificationCenter *)center notification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
}

- (void)dismissedContentDisplay:(RFAction *)action content:(RFContent*)content {
}

@end

SceneDelegate.h

#import <UIKit/UIKit.h>

@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

SceneDelegate.m

#import "SceneDelegate.h"
#import <RichFlyer/RichFlyer.h>

@implementation SceneDelegate

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    if (![scene isKindOfClass:[UIWindowScene class]]) {
        return;
    }
    UIWindowScene *windowScene = (UIWindowScene *)scene;

    // 画面(Window)の生成
    self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
    // self.window.rootViewController = ...
    [self.window makeKeyAndVisible];

    // OSにプッシュ通知の受信許可をリクエスト
    [RFApp requestAuthorization:[UIApplication sharedApplication]
                                applicationDelegate:[UIApplication sharedApplication].delegate];

    // 自分で通知受信時のOptionを設定する場合
    //[RFApp requestAuthorization:[UIApplication sharedApplication]
    //                                         options:RFAuthorizationOptionAlert|RFAuthorizationOptionBadge|RFAuthorizationOptionSound
    //                             applicationDelegate:[UIApplication sharedApplication].delegate];
}

@end

Info.plistには以下のようにSceneDelegateを指定する設定を追加します。

<key>UIApplicationSceneManifest</key>
<dict>
    <key>UIApplicationSupportsMultipleScenes</key>
    <false/>
    <key>UISceneConfigurations</key>
    <dict>
        <key>UIWindowSceneSessionRoleApplication</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>Default Configuration</string>
                <key>UISceneDelegateClassName</key>
                <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
            </dict>
        </array>
    </dict>
</dict>