• お知らせ一覧画面をカスタマイズする

    レイアウトをカスタマイズする

    描画に関するソースコードは PopinfoListViewController クラスで完結しています。
    マージンや高さなどは PopinfoViewConfiguration クラスで定義されます。
    この2つのクラスを修正していただくことにより、レイアウト上の様々なカスタマイズが可能です。

     

    特定のカテゴリのみを一覧に表示する

    お知らせ一覧画面用のクラス(PopinfoListViewController)のインスタンスを以下のように生成し、category プロパティに@”news”という文字列をあてます。
    これによって、このお知らせ一覧画面には、「news」カテゴリの配信のみが表示されます。

    let newsListVC = PopinfoListViewController(nibName: "PopinfoListViewController", bundle: Bundle.main)
    newsListVC.category = "news"

     

    届いたお知らせのカテゴリに応じて、表示するお知らせ一覧を動的に変えたい

    PopinfoReceiver デリゲートメソッド func popinfoReceiver(_ popinfoReceiver: PopinfoReceiver, didReceivePopinfoMessage messageId: Int, category: String, result: Bool)  を記述してください。
    プッシュ通知受信後、サーバーとの通信が完了したときに、このデリゲートメソッドがコールされます。

    サーバーとの通信が完了しているため、このデリゲートメソッドの引数の category には届いたお知らせのカテゴリ文字列が入っています。
    以下のサンプルのように、カテゴリに応じてお知らせ一覧画面に表示するお知らせのカテゴリを変える処理を記述してください。

    func popinfoReceiver(_ popinfoReceiver: PopinfoReceiver, didReceivePopinfoMessage messageId: Int, category: String, result: Bool) {
    	// PopinfoListViewController の category プロパティに category を代入し、
    	// お知らせ一覧画面に表示するお知らせをそのカテゴリに絞り込む。
    	listVC.category = category
    }

     

    既読のお知らせ詳細タイトルの文字色を変更する

    PopinfoViewConfiguration.m 内の kListViewColorUseWhenRead が YES になっていることを確認します。

    文字色を変えたい場合は、PopinfoListViewController.m 内に記述されているtableView:cellForRowAtIndexPath: において、titleLabel.textColor = [UIColor grayColor];message.piUnread の値に応じて変更してください。

     

    未読/既読を管理する

    メッセージの未読件数を取得してタブにバッジを表示したい

    メッセージの未読数を取得する場合、PopinfoReceiver クラスのgetUnreadMessagesCounts: メソッドを利用します。

    // バッジを付けたい UITabBarItem を指定する
    let tabBarItem = self.tabBarController?.tabBar.items?[1]
    // 未読数を取得する
    let number = PopinfoReceiver.shared.getUnreadMessagesCounts("")
    // 未読がある場合はタブにバッジを付ける
    if number > 0 {
    	tabBarItem?.badgeValue = "\(number)"
    } else {
    	tabBarItem?.badgeValue = nil
    }

     

    特定のメッセージを強制的に既読に変更したい

    特定のメッセージを強制的に既読に変更する場合、PopinfoReceiver クラスのchangeMessageToRead: メソッドを利用します。

    ここでは、プッシュ通知到達時に、通知されたメッセージを強制的に既読に変更する例をご紹介します。
    以下のように、プッシュ通知が到達した際にコールされる PopinfoReceiver デリゲートメソッド func popinfoReceiver(_ popinfoReceiver: PopinfoReceiver, didReceivePopinfoMessage messageId: Int, popup: String, payload: [AnyHashable : Any]) 内に記述します。

    func popinfoReceiver(_ popinfoReceiver: PopinfoReceiver, didReceivePopinfoMessage messageId: Int, popup: String, payload: [AnyHashable : Any]) {
    	PopinfoReceiver.shared.changeMessage(toRead: messageId)
    }
  • お知らせ詳細画面をカスタマイズする

    レイアウトをカスタマイズする

    描画に関するソースコードは PopinfoDetailViewController クラスで完結しています。
    マージンや高さなどは PopinfoViewConfiguration クラスで定義されます。
    この2つのクラスを修正していただくことにより、レイアウト上の様々なカスタマイズが可能です。

     

    URLを開くボタンを消す

    リンク先 URL を指定せずに配信した際に、お知らせ詳細画面上で URL を開くボタンを表示したくない場合は、PopinfoDetailViewController.m の changeColorOfUrlButton メソッド内の「self.navigationItem.rightBarButtonItem = nil;」のコメントアウトを外してください。

     

    URLを開くボタン押下時の処理をオーバライドする

    PopinfoDetailViewController の didSelectOpenUrl メソッド内に独自処理を記述してください。
    Swift で利用する場合はこのクラスを継承の上、メソッドをオーバーライドしてください。

    override func didSelectOpenUrl() {
    	super.didSelectOpenUrl()
    	// URLを開くボタンが押下された際に行いたい処理をここに記述(任意)
    }

     

    お知らせ詳細画面を開かずにお知らせ詳細内容を取得する

    メッセージ ID を取得できるシーン(プッシュ通知受信時にコールされるデリゲートメソッド popinfoReceiver:didReceivePopinfoMessage:category:result: など)で、以下のように取得できます。

    let detailVC = PopinfoDetailViewController(nibName:"PopinfoDetailViewController", bundle:Bundle.main)
    detailVC.messageId = messageId
    print("Title = \(String(describing: detailVC.message.piTitle))")
    print("Contents = \(String(describing: detailVC.message.piContent))")
    print("Url = \(String(describing: detailVC.message.piUrl))")
  • アプリ内メッセージをカスタマイズする

    アプリ内メッセージとは

    アプリ内メッセージとは、アプリ起動中のユーザーに向けてポップアップなどのメッセージを表示させることができる機能です。

    この機能を使用することで、下記のようなことが実現できます。

    • お知らせを OFF にしているユーザーに対してアプローチを行う
      • (お知らせを ON にするように設定画面への遷移を促す、など)
    • アプリのトップ画面を開いた際、キャンペーンなどのバナーを表示させる
    • 商品をカートに入れたユーザーに対しクーポンを付与するようなバナーを表示させる

    イベントトラッキングを付与する

    アプリ内メッセージを表示させるためには、必ずイベントトラッキングを付与する必要があります。
    イベントトラッキングの付与には下記のメソッドを呼び出してください。

    PopinfoReceiver.shared.trackEvent("イベントキー名", value: [
    	"testName1": "testVal1",
    	"testName2": "testVal2"
    ])

    第1引数にはイベントのキー名を、第2引数にはイベントのキーに対する値を辞書型で格納します。

     

    デリゲートメソッドについて

    公開されている各種デリゲートを利用し、アプリ内メッセージの一部の処理に割り込むことが出来ます。
    デリゲートメソッドを利用するためには、まず以下のように実装を行います。

    • PopinfoReceiver と同様に PopinfoEventActionReceiver のクラスのインスタンスとプロトコルの宣言を行います。
    • App 起動時にコールされる application:didFinishLaunchingWithOptions: 内で同クラスのインスタンスを生成します。
    class AppDelegate: UIApplicationDelegate, UNUserNotificationCenterDelegate, PopinfoReceiverDelegate, PopinfoEventActionReceiverDelegate {
    	var popinfoReceiver: PopinfoReceiver!
    	var popinfoEventActionReceiver: PopinfoEventActionReceiver!
    	func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    		self.popinfoReceiver = PopinfoReceiver.shared
    		self.popinfoReceiver.delegate = self
    		self.popinfoEventActionReceiver = PopinfoEventActionReceiver.shared
    		self.popinfoEventActionReceiver.delegate = self
    		// ...省略...
    	}
    	// ...省略...
    }

    デリゲートメソッドの詳細についてはAPIドキュメントを参照してください。

     

    組み込み側でメッセージの表示可否を判定する

    func popinfoEventActionReceiver(_ popinfoEventActionReceiver: PopinfoEventActionReceiver, shouldFireActionByEvent event: String, withCategories categories: [String]) -> Bool { 
    	// originalCheckResult の実装は省略
     	originalCheckResult(event: event, categories: categories) 
    }

    実装しなかった場合はYESが返却されたものとして扱われます。

     

    条件合致通知に失敗した時にリトライするかどうかを決める

    func popinfoEventActionReceiver(_ popinfoEventActionReceiver: PopinfoEventActionReceiver, shouldFireActionByEvent event: String, withCategories categories: [String]) -> Bool {
    	// originalCheckResult の実装は省略
    	originalCheckResult(event: event, categories: categories)
    }

    実装しなかった場合はNOが返却されたものとして取り扱われます。

    管理画面で設定したリトライ回数を超えてリトライが行われることはありません。

    イベントアクションの発火が行われなかった場合、発火回数のカウントはされません。

     

    アプリ内メッセージ表示直前の校閲

    func popinfoEventActionReceiver(_ popinfoEventActionReceiver: PopinfoEventActionReceiver, shouldFireActionByEvent event: String, withCategories categories: [String]) -> Bool { 
      	// originalCheckResult の実装は省略
      	originalCheckResult(event: event, categories: categories)
    }

    アプリ内メッセージを表示する直前にコンテンツを編集することができます。

    例としてコンテンツに$userのように仮置きの文字列を入れて、デバイスに登録してあるユーザ情報と置き換えることで個人宛のメッセージを表示するような実装が可能です。

     

    デバッグモードについて

    PopinfoConfiguration.m において popinfoTestLogUse を YES に設定すると、アプリ内メッセージを表示するためのイベントが発生したタイミングで、コンソールにイベントのキー名を表示することが出来ます。

    コンソール表示の書式

    <キー名> matched. (現在の1日の表示回数,1日の最大表示回数)(トータル表示回数、トータル最大表示回数)

    コンソール表示の例

    <app.top> matched. (1,5)(1,-)

     

    APIの設定値を変更する

    アプリ内メッセージにおいては、 以下の設定値を変更することができます。
    付属のファイル SdkSettings.plist において、該当箇所を下記条件に従って変更してください。

    キー 説明 初期値 最小値 最大値
    EventActionApiCallMaxWaitSec アプリ内メッセージ用のAPIコールにおけるタイムアウト値(単位:秒) 10 5 60
    EventActionApiRetryCountLimit アプリ内メッセージ用APIのコールが失敗した際に、再試行を行う回数の最大値 5 0 10

    変更後の値がそれぞれの最小値以下または最大値以上だった場合は初期値が適用されます。

     

  • イベントトラッキングをカスタマイズする

    カスタムイベントを記録する

    カスタムイベントを記録する場合、PopinfoReceiver クラスの trackEvent:value: メソッドを利用します。このメソッドの引数は、イベントのキー名と、キーに対する値(クエリ文字列に対応する NSDictonary)です。

    以下の例では、キー名が keyName、キーに対する値が testName1=testVal1&testName2=testVal2 で記録されます。

    PopinfoReceiver.shared.trackEvent("keyName", value: ["testName1":"testVal1", "testName2":"testVal2"])

    キー名のみを記録したい場合は、以下のような記述となります。

    PopinfoReceiver.shared.trackEvent("keyName", value: [:])

    カスタムイベントの文字制限について

    カスタムイベントには、以下の制限があることにご注意ください。

    • キー名は、英数字([a-zA-Z0-9])、アンダースコア(_)、ピリオド(.)、ハイフン(-)のみ使用できます。
    • キー名の先頭にアンダースコア(_)は使用できません。
    • キー名が nil や空文字の時は記録できません。
    • 文字数制限は、キー名が 32 文字、キーに対する値はトータルで 512 文字 です。

    イベントトラッキングの値にアプリ側の定義値を付与する

    イベントトラッキングの値にアプリ側で定義した値を 常に 付加したい場合は、PopinfoReceiver クラスの addEventTrackingExtraName:value: メソッドを利用してください。
    このメソッドを実行すると、引数に与えられた name と value が &name=value という形で展開され、全てのイベントトラッキングの値の末尾に付加 されます。

    値が付加されるタイミングは、 popinfoSDK がサーバーに対してイベントトラッキングを送信するときとなります。

    PopinfoReceiver.shared.addEventTrackingExtraName("name1", value: "value1")

    イベントトラッキングの値からアプリ側の定義値を削除する

    実行した addEventTrackingExtraName:value: を無効化したい場合は、PopinfoReceiver クラス の removeEventTrackingExtra メソッドをコールしてください。
    これにより、本 SDK 内部でキャッシュされたアプリ側定義値に関する name や value 値が全てクリアされます。

    PopinfoReceiver.shared.removeEventTrackingExtra()

     

    アプリ側定義値の文字数制限について

    アプリ側定義値の付加に関しては、以下の制限があることにご注意ください。

    • name には、nil、空文字、popinfo 予約語(pModel、pOsVer、pPopinfoVer)を使用することはできません。
    • value が nil のときは、空文字に変換されます。
    • 付加可能な最大文字数(上記例の name1=value1&name2=value2 部分の最大文字数)は、1024 文字 です 。
      • 超過した場合、本来付加すべき文字列は 破棄 され、かわりに &OmittedValues=文字数 が付加されます。
    • すでに設定した name に対して異なる value を設定してメソッドを実行すると、value が 上書きされます 
  • ユーザ属性を登録する方法について

    画面からユーザ属性を変更する

    PopinfoSegmentSettingsViewController を使い、エンドユーザーの属性を設定することができます。

    FANSHIP では、性別や年齢層、趣味などといった属性をエンドユーザーに設定することができます。
    設定された属性は、「 属性絞り込み配信 」などで利用することができます。

    ViewControllerの初期化方法は以下の通りです。

    let segmentVC = PopinfoSegmentSettingsViewController(nibName:"PopinfoSegmentSettingsViewController", bundle:Bundle.main)
    segmentVC.delegate = self

    APIからユーザ属性を変更する

    ユーザーの属性を設定する場合、PopinfoReceiver クラスの setSegments:forKey:completion: メソッドを利用します。

    1. 属性キー 200 に属性値 4 をセットする例です。
      PopinfoReceiver.shared.setSegments([4], forKey: "200") { isOk, errorCode in 
          // 設定の結果をダンプ 
          print("setSegments isOK = \(String(describing: isOk)), errorCode = \(String(describing: errorCode))") 
      }
    2. 属性キー 800 に属性値 218 と 219 をセットする例です。
      PopinfoReceiver.shared.setSegments([218, 219], forKey: "800") { isOk, errorCode in 
          // 設定の結果をダンプ 
          print("setSegments isOK = \(String(describing: isOk)), errorCode = \(String(describing: errorCode))") 
      }
    3. 属性キー 200 の属性値をクリアする例です。
      PopinfoReceiver.shared.setSegments([], forKey: "200") { isOk, errorCode in 
          // 設定の結果をダンプ print("setSegments isOK = \(String(describing: isOk)), errorCode = \(String(describing: errorCode))") 
      }

     

  • 多言語化対応する

    アプリ上で表示される文字列を多言語化する

    Xcode 上でプロジェクトに対して、各言語ごとに Localizable.strings ファイルを作成していただく必要があります。

    以下、導入の手順となります。

    1. アプリプロジェクトを Xcode で開き、ツールバーから File > New > File と進みます。
      表示された画面上で iOS > Resource > Strings File をクリックし、ファイル名を Localizable.strings で新規作成します。
    2. Xcode 画面左側のナビゲーションエリアにおいて、作成された Localizable.strings を選択します。この状態で、画面右側のユーティリティエリアの中段 Localization において、 Localize… ボタンをクリックします。
    3. Finder でプロジェクト内のファイルを確認すると、en.lproj フォルダ内に、Localizable.strings ファイルが作成されていることが確認できます。
    4. Xcode 上で、「PROJECT」の Info タブを開くと、画面中段 Localizations において、各国語バージョンを加えることができる「+」ボタンがあります。
      このボタンをクリックして、 Japanese を選択します。
    5. Finder でプロジェクト内のファイルを確認すると、en.lproj フォルダと同列のディレクトリに ja.lproj フォルダが作成されます。その中にも Localizable.strings ファイルが作成されています。
    6. 英語、日本語の Localizable.strings ファイル内に、以下の内容をそれぞれコピーして貼付けてください。 
      "popinfoTitle1" = "Information"; 
      "popinfoLabel1" = "No message received.";
      "popinfoButton1" = "Open in Safari";
      "popinfoButton3" = "Close";
      "popinfoDialog5" = "Error";
      "popinfoDialog6" = "A network error occurred, please try again later.";
      "popinfoDialog7" = "Connection refused, please restart your app.";
      "popinfoTitle1" = "お知らせ一覧"; 
      "popinfoLabel1" = "お知らせはありません";
      "popinfoButton1" = "URLを開く";
      "popinfoButton3" = "閉じる";
      "popinfoDialog5" = "Error";
      "popinfoDialog6" = "通信に失敗しました。通信状況の良い場所でもう一度お試しください。";
      "popinfoDialog7" = "接続エラーが発生しました。通信状態の良好な場所でアプリを再起動してください。";

    「設定 > アプリ名」内で表示される文字列を多言語化する

    「設定 > アプリ名」で表示される文字列は、SDK 内の Settings.bundle > Root.strings ファイルに記述されている内容が反映されます。

    ここでは中国語を例に説明します。

    1. Xcode 上で、左側ナビゲーションエリアに配置された SDK ファイル群のうち、Settings.bundle が存在することを確認してください。
      その配下に、英語用の en.lproj フォルダと Root.plist ファイル、日本語用の ja.lproj フォルダと Root.plist ファイルがあります。
    2. Settings.bundle を右クリックし「Show In Finder」を選択します。
    3. Finder が現れます。Settings.bundle を右クリックし「パッケージの内容を表示」をクリックします。
    4. 表示された en.lproj フォルダを同じ階層にコピーします。
    5. コピーしたフォルダの名前を zh-Hans.lproj (簡体字中国語)に変更します。
      そして、このフォルダ配下の Root.strings ファイル内に記述されているキーに対する値を中国語に直します。

     

  • スプリットビュー(iPad)を実装する

    スプリットビューは、一つの画面にお知らせ一覧画面とお知らせ詳細画面を並べるものです。
    SDK では、UISplitViewController を継承したビューコントローラ PopinfoPadViewController を提供しており、iPad 時に活用できます。

    画面イメージは以下のとおりです。

    • 横画面表示時
      左側にお知らせ一覧画面、右側にお知らせ詳細画面が配置されます。左側のお知らせ一覧画面の行をタップすると、連動して右側のお知らせ詳細画面の表示内容が変わります。

      4-1.png
    • 縦画面表示時
      お知らせ詳細画面が画面領域全体に表示されます。
      ナビゲーションバーの「お知らせ一覧」ボタンをタップすると、お知らせ詳細画面の上に重なる形でお知らせ一覧画面が表示されます。

      4-2.png 4-3.png

    PopinfoPadViewController を使い、iPad に対応する

    PopinfoPadViewController クラスの初期化には initWithNibName を用い、nib ファイルには nil を指定してください。
    また、PopinfoViewConfiguration.m 内の「kIpadSplitViewUse」値を YES に変更していただく必要があります。
    以下、実装例です。(PopinfoPadViewController に直接関連する部分のみ記述します。)

      1. PopinfoPadViewController を生成します。ここでは、アプリ起動時に生成し、タブの3番目に配置する例です。
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        	// PopinfoPadViewController を生成し、tabBarController の3番目のアイテムに配置する
        	let padVC = PopinfoPadViewController(nibName: nil, bundle:nil)
        	padVC.tabBarItem = UITabBarItem(tabBarSystemItem: .favorites, tag: 2)
        	self.tabBarController.viewControllers = [viewController1, viewController2, padVC]
        }
      2. プッシュ通知受信時における PopinfoPadViewController の動作を実装します。 PopinfoPadViewController が配置されているタブを選択し、表示を更新します。
        func popinfoReceiver(_ popinfoReceiver: PopinfoReceiver, didReceivePopinfoMessage messageId: Int, popup: String, payload: [AnyHashable : Any]) {
        	if UIDevice.current.userInterfaceIdiom == .pad {
        		// iPad時の処理
        		// PopinfoPadViewController のタブを選択する
        		let padVC = self.tabBarController.viewControllers[2]
        		self.tabBarController.selectedViewController = padVC
        		
        		// メッセージIDを設定し、表示を更新する
        		padVC.messageId = messageId
        		padVC.detailVC.reloadMyViews()
        	} else {
        		// iPhone時の処理
        	}
        }
  • Today Extensionを導入する

    iOS 8から通知センターに Today Extension(ウィジェット)を設置できるようになりました。
    実装は必須ではありませんが、ここでは、最新のお知らせタイトルを表示する方法についてご紹介します。

    Extensionの作成

    File > New > Target > iOS > Application Extension から、Today Extension を選択し、Extension を作成します。

    12-1.png

     

    App Groupの作成

    アプリ本体と Today Extension でデータを共有するためには、App Group を作成することが必要です。

    1. ブラウザから iOS Dev Center にログインし、App Groups から App Group を作成します。12-2.png
    2. App IDs から iPhone アプリを選択し、App Groups を有効化します。プロビジョニングプロファイルは再作成してください。12-3.png
    3. iOS Dev Center において、Today ExtensionのApp ID を作成します。(Xcode によって自動的に作られている場合もあります。)
    4. ここからは Xcode 上の作業となります。
    5. iPhone アプリと Today Extension の TARGETS において、それぞれ Capabilities から App Groups を有効化します。12-4.png

    Today Extensionのコーディング

    Extension を作成した際、Xcode のアプリプロジェクト上で、TodayViewController.h、TodayViewController.m、MainInterface.storyboard などが自動で生成されます。
    MainInterface.storyboard において、最新のお知らせのタイトルと日付を表示するための UILabel を作成してください。

    そして、TodayViewController.m の viewDidLoad 内に、以下を記述してください。

    // 高さ変更
    self.preferredContentSize = CGSize(width: 0, height: 100) 
    
    // 年月日ラベル用フォーマッタ
    let formatter = DateFormatter()
    let calendar = Calendar(identifier: .gregorian)
    formatter.calendar = calendar
    formatter.locale = NSLocale.system
    formatter.timeZone = NSTimeZone.system
    formatter.dateFormat = "yyyy/MM/dd" 
    
    // ラベルの更新
    let ud = UserDefaults(suiteName: "App Group 名")
    if ud != nil && ud?.object(forKey: "messageTitle") != nil {
    	self.titleLabel.text = ud!.object(forKey: "messageTitle")
    	self.timeLabel.text = formatter.string(from: ud!.object(forKey: "messageTime") as! Date)
    } else {
    	self.titleLabel.text = "お知らせはありません"
    	self.timeLabel.text = ""
    }

    アプリ側のコーディング

    AppDelegate.m において、お知らせを FANSHIP サーバーから取得した際にコールされる PopinfoReceiver デリゲートメソッド func popinfoReceiver(_ popinfoReceiver: PopinfoReceiver, updateMessagesResult result: Bool) を実装します。
    そのタイミングで、Today Extension とデータを共有できる領域に最新のお知らせを保存します。

    func popinfoReceiver(_ popinfoReceiver: PopinfoReceiver, updateMessagesResult result: Bool) {
    	// 通信に失敗した場合は return
    	guard result else { return }
    	
    	// 最新のお知らせを取得する
    	let myListVC = PopinfoListViewController(nibName: "PopinfoListViewController", bundle: Bundle.main)
    	let messages = myListVC.retrieveAllPopinfoMessages()
    	guard messages.count > 0 else { return }
    	let latestMessage = messages[0]
    
    	// Today Extension と連携するため、共有領域に最新のお知らせのタイトルと日時を保存する
    	guard let ud = UserDefaults(suiteName: "App Group 名") else { return }
    	ud.set(latestMessage.piTitle, forKey: "messageTitle")
    	ud.set(latestMessage.piTime, forKey: "messageTime")
    }
  • App Clipを導入する

    App Clipの概要

    App Clip の概要や作成方法については公式ドキュメントおよび WWDC 2020 のビデオをご覧ください。
    後者は日本語字幕もあり、Xcode上の操作方法についても実際の画面表示にそってとても丁寧に説明されています。

    なお、本ドキュメントにおいては App Clip に対する Parent App (すなわち、フルバージョンのアプリ)について、App Store Review ガイドラインに従い メインのApp または単に App と呼称します。

     

    FANSHIP SDKで出来ること

    本SDK を App Clip にも組み込むことで、 App Clip で popinfo ID を取得した場合、ID をメインのAppに引き継ぐことができます。

    また、App Clip に向けたプッシュ通知については部分的にご利用いただけます。下記の表をご参照ください。

    機能 利用可能状況
    即時配信 ご利用いただけます
    予約配信 ご利用いただけます
    位置連動配信 配信を届けられない場合があります(※1)
    Wi-Fi配信 ご利用いただけません(※2)
    Bluetooth配信 配信を届けられない場合があります(※1)
    アプリ内メッセージ ご利用いただけます

     

    ※1 : App Clip ではバックグラウンドタスクが動作しません。
    そのため、 位置連動配信 や Bluetooth配信 において、エンドユーザーが App Clip 上でプッシュ通知を受け取れるのは  App Clip が起動中、かつ、その時点で配信対象になっている場合  に限られます。

    ※2 : App Clip は Access WiFi Information Capability を設定できないため、これを利用する Wi-Fi 配信 はご利用いただけません。

     

    App ClipへのSDK組み込み手順

    事前確認

    SDKを組み込む前に、下記 App Clip を組み込むための準備が整っていることをご確認ください。

    • プロジェクトの Team ID がエンタープライズプログラムに 加入していない
    • プロジェクトに App Clip 用ターゲットが追加されている
    • メインのApp および App Clip の両方において、Capabilities に App Groups が追加されている
    • メインのApp および App Clip の両方が同一の App Groups に属している

    App Clip は、エンタープライズプログラムにおいて利用することができません。
    エンタープライズプログラムでは On Demand Install Capable が自動的に付与されないため、シミュレーター向けビルドを除き、ビルドが失敗します。

    App Clip 用ターゲットを追加する手順については Explore app clips をご覧ください。

     

    フレームワーク追加

    App Clip ターゲットにおける TARGETS > Build Phases > Link Binary With Libraries に以下を追加してください。
    Embed オプションが表示されるものについては、いずれも Do Not Embed をお選びください。

    • CoreLocation.framework
    • CoreTelephony.framework
    • SystemConfiguration.framework
    • libPopinfoReceiverLib.a

     

    SearchPathの追加

    Module mapを利用する場合

    Swift Compiler - Search Paths > Import Paths に、本 SDK 付属の modulemap ファイルを内包するディレクトリのパスをセットします。

    たとえば、 $(SRCROOT)/MyApp/popinfo/lib/ に a ファイルが存在している場合、modulemap を内包するディレクトリにのパスは $(SRCROOT)/MyApp/popinfo/lib/Modules/PopinfoReceiver です。

     

    Bridging-Headerを利用する場合

    Bridging Header のパスを Swift Compiler - General > Objective-C Bridging Header にセットします。

     

    TargetMembershipの編集

    本 SDK の付属ファイルのうち 下記を除くすべてのファイル を、App Clip ターゲットに追加します。

    • ヘッダ(*.h)ファイル
    • Settings.bundle(※3)

    App Clipターゲットに追加するには

    13-1.png

    ※3 : App Clip は設定画面をもたないため、Settings.bundle を含めてしまうと App Store へのデリバリ時に ITMS-90047: Disallowed paths が発生し、デリバリが失敗します。

     

    カスタムフラグの追加

    App Clip ターゲットの Build Settings において、Apple Clang - Preprocessing > Proprocessor Macros に含まれる各 Configuration に対して APPCLIP=1 を追加します。

    13-2.png

    App Clip 開発時は Active Complilation Conditions を利用して処理を分岐させることが多々あると思いますが、このカスタムフラグとは別に上記の Proprocessor Macros の設定が必要です。
    Active Compilation Conditions を設定しただけでは本SDKのは動作しませんので、ご注意ください。

    13-3.png

     

    SdkSettings.plistの設定

    SdkSettings.plist において、以下のように値をセットします。

    • FanshipAppClipUse に YES (1) を入力します13-4.png
    • FanshipAppGroupName に、App Clip が属する App Groups の名前を入力します
      13-5.png

     

    プッシュ通知の一時許可

    App Clip では一定条件のもと、ユーザーに許諾ダイアログを表示することなくプッシュ通知を送る方法が存在します。

    Info.plist の App Clip 以下に Requests ephemeral user notifications を追記し、値を YES とすることで、起動後8時間に限りプッシュ通知を送信できるようになります。

    13-6.png

    この設定はユーザーが App Clip カードにおいて無効にすることも出来ます。

    13-8.png

    その場合、iOSからは「プッシュ通知を許可しない」場合と同等に扱われます。

    詳細については Enabling Notifications in App Clips をご参照ください。

     

    コーディング

    App Clip上で Popinfo ID を取得し、プッシュ通知を届けるために必要な実装を説明します。

    1. AppDelegate の冒頭で PopinfoReceiver をインポートします。
      import PopinfoReceiver
    2. App がアクティブになった時にコールされるアプリケーションデリゲートメソッド applicationDidBecomeActive: 内で、以下のように実装します。
      func applicationDidBecomeActive(_ application: UIApplication) {
      	self.popinfoReceiver.loadSettings()
      }
      iOS13以降のみをサポートするAppで SceneDelegate をご利用の場合は、applicationDidBecomeActive: ではなく、sceneDidBecomeActive: に記述してください。
    3. APNs トークンが iOS から付与される際にコールされるアプリケーションデリゲートメソッドを以下のように記述し、その中に FANSHIP の処理を記述します。
      func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      	self.popinfoReceiver.registerToken(deviceToken)
      }

      以上を実装することで、App Clip の起動時にPopinfo IDの取得およびデバイストークンの取得が完了します。

    アップグレードについて

    メインのAppとApp Clipの両者の Capabilities に同一の App Groups を設定することでPopinfo IDを引き継ぐことができます。

     

    App Clip関連ドキュメント

    App Clip の実装に関しては、冒頭で紹介した動画の他に公式ドキュメントが公開されています。

    下記、実装に役立つリンクを列挙しましたので、App Clip 開発時にお役立てください。

    ドキュメント

    動画

    Apple公式サンプルコード

  • アップデート時の注意点

    引き継ぐ必要のある項目を確認する

    SDKをダウンロードしてプロジェクトに上書きする際に既存の設定内容を予め一時ファイルに退避させておく必要があります。

    ダウンロード後に編集されている可能性が高いファイルは以下の通りです。

    • PopinfoConfiguration.m
    • SdkSettings.plist
    • Settings.bundle/Root.plist
    • PopinfoViewConfiguration.m
    • PopinfoListViewController.m
    • PopinfoDetailViewController.m

    上書き後に引き継ぐ必要のある項目について一時ファイルからコピーしてください。

     

    参照パスを確認する

    旧SDKとは別の場所に新SDKを組み込む場合には参照パスを更新する必要があります。

    プロジェクトの TARGETS > Build Settings にある、Search Paths > Library Search Paths を更新してください。

     

    CoreDataバージョンを確認する

    CoreDataモデルバージョンは常に最新バージョンを指定してください。
    バージョンが適切に設定されていない場合、アプリが異常終了することがあります。

     

    SDK更新後のアプリの動作を確認する

    SDKの更新を行った際は旧アプリからのバージョンアップを想定したテストを行うなど、必要な動作確認をお願いします。