stotic-dev
@stotic-dev

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【IOS】Univarsal Linksでアプリが起動しない

解決したいこと

swiftでUnivarsal Linksを用いてURLリンクをタップしたらアプリが起動する機能を実装しようとしています。

発生している問題・エラー

Univarsal Linksの実装に必要な以下手順を踏みましたが、
実機にアプリをインストールした後apple-app-site-associationを配置したFirebase HostingのURLリンクをタップしてもアプリが起動しませんでした。
何か他に確認が必要な箇所、漏れている手順などありますでしょうか?

<Univarsal Links実装手順>
①Apple Developerにて対象のAppIDに「Associated Domains」チェックを入れる
(AppIDの修正に伴いProvisioning Profileも更新)
②AppDelegate.swiftにapplication(_:continue:restorationHandler:)を追加
③Firebase Hostingの/.well-knownディレクトリに以下apple-app-site-associationを配置してデプロイ

public
 |_ index.html
 |_ .well-known
   |_ apple-app-site-association

④Xcodeのアプリ対象TargetのCapabilityに「Associated Domains」を追加して、
 applinks:<デプロイしたFirebase Hostingのドメイン>を設定
⑤アプリをインストールする実機の[設定]->[デベロッパ]->[Associated Domains Development]をONにする
⑥実機にアプリをインストールしたあと、以下コマンドでCDNにapple-app-site-associationが反映されているか確認(HTTP/1.1 200 OKContent-Type: application/jsonが返ってきていること)

curl -v https://app-site-association.cdn-apple.com/a/v1/<デプロイしたFirebase Hostingのドメイン>

該当するソースコード

・apple-app-site-association

{
    "applinks":
    {
        "details":
        [
            {
                "appIDs":
                [
                    "[チームID].[アプリのバンドルID]"
                ],
                "components":
                [
                    {
                        "/": "*",
                        "comment": "すべてのパスを対象にする"
                    }
                ]
            }
        ]
    }
}

・firebase.json

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": [
    {
      "source": "functions",
      "codebase": "default",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log"
      ],
      "predeploy": [
        "npm --prefix \"$RESOURCE_DIR\" run lint",
        "npm --prefix \"$RESOURCE_DIR\" run build"
      ]
    }
  ],
  "hosting": {
    "public": "public",
    "appAssociation": "NONE",
    "rewrites": [ {
      "source": "**",
      "destination": "/.well-known/apple-app-site-association"
    } ],
    "headers": [
      {
        "source": "/.well-known/apple-app-site-association",
        "headers": [
          {"key": "Content-Type", "value": "application/json"}]
      }
    ]
  }
}

・AppDelegate.swift

//
//  AppDelegate.swift
//  FreTre
//

import UIKit
import FirebaseCore
import UserNotifications
import FirebaseAuth
import FirebaseFirestore
import FirebaseMessaging
import IQKeyboardManagerSwift

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        FirebaseApp.configure()
        signInApp()
        Messaging.messaging().delegate = self
        
        setupIQKeyboard()
        registarRemoteNotification(application: application)
        
        return true
    }
    
    func setupIQKeyboard(){
        let keyboardManager = IQKeyboardManager.shared
        keyboardManager.enable = true
        keyboardManager.keyboardDistanceFromTextField = K.keyboardDistance
        keyboardManager.enableAutoToolbar = false
        keyboardManager.shouldResignOnTouchOutside = true
        
    }
    
    func registarRemoteNotification(application:UIApplication){
        if #available(iOS 10.0, *){
            UNUserNotificationCenter.current().delegate = self
            UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert], completionHandler: {(granted, error) in
                if (granted)
                {
                    DispatchQueue.main.async {
                        UIApplication.shared.registerForRemoteNotifications()
                    }
                }
                else{
                    //Do stuff if unsuccessful...
                }
            })
        }
        else { //If user is not on iOS 10 use the old methods we've been using
            let notificationSettings = UIUserNotificationSettings(
                types: [.badge, .sound, .alert], categories: nil)
            application.registerUserNotificationSettings(notificationSettings)
            
        }
    }
    
    func signInApp(){
        Auth.auth().signInAnonymously { resutl, error in
            if let error = error {
                print(error.localizedDescription)
            }else{
                print("succes login!")
            }
        }
    }
    
    func updateFmcToken(teamId: String, teamUUID: String, fmcToken: String){
        let updateData = [K.FStore.member_Id:K.uid,K.FStore.token: fmcToken] as! [String:Any]
        Firestore.firestore().collection(K.FStore.c_Tokens).document(teamUUID).collection(K.FStore.subc_TokenMember).document(K.uid).setData(updateData) { error in
            if let error = error{
                print(error.localizedDescription)
                return
            }else{
                print("success update fmcToken")
                return
            }
        }
    }
    
    // MARK: UISceneSession Lifecycle
    
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    }
    
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        print("open")
        return true
    }
    
    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        print("open")
        return true
    }
    
    // remote notificationの受信メソッド
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult {
        
        // Print full message.
        print(userInfo)
        
        return UIBackgroundFetchResult.newData
    }
    
}


// MARK: -extention for Firebase Messaging delegate method
extension AppDelegate:MessagingDelegate{
    
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("fcmToken:\(fcmToken!)")
        guard let fmcToken = fcmToken else { return }
        UserdefaultsManager.setString(value: fmcToken, key: K.UserD.fmcToken)
        
        if let teamId = UserdefaultsManager.getString(key: K.UserD.teamId), let teamUUID = UserdefaultsManager.getString(key: K.UserD.teamUUID) {
            updateFmcToken(teamId: teamId, teamUUID: teamUUID, fmcToken: fmcToken)
        }
        
    }
}

// MARK: - extension for notification delegate method
extension AppDelegate:UNUserNotificationCenterDelegate{
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
        let userInfo = notification.request.content.userInfo
        
        // Print full message.
        print(userInfo)
        
        // Change this to your preferred presentation option
        return [[.badge,.sound]]
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
        let userInfo = response.notification.request.content.userInfo
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print full message.
        print(userInfo)
    }
}

自分で試したこと

apple-app-site-associationをルート直下にも配置
・適当なサイトにUnivarsal LinksのURLのリンクを埋めてそこからUnivarsal Linksを起動してみる
AASA VALIDATORで対象のUnivarsal Linksのテストを実施して問題ないことを確認
スクリーンショット 2023-06-18 13.42.24.png
・Provisioning Profileが「Associated Domains」を設定したAppIDと紐付いているか確認
スクリーンショット 2023-06-18 13.48.13.png
・実機の[設定]->[デベロッパ]->[UNIVERSAL LINKS]->[Diagnostics]にてFirebase HostingのURLを検証し問題ないことを確認
IMG_4586.jpg
・entitlementsファイルのTarget Membershipにチェックが入っていること、
 CapabilityのAssociated Domainsに追加した値と同じ値が設定されていることを確認
スクリーンショット 2023-06-18 14.56.52.png

環境

実機
バージョン:IOS16.3.1
機種:iPhone SE(第2世代)

Xcode
バージョン:14.3

0

1Answer

↓こちらの記事は参考になりませんか?
(少し前の記事のため、やり方が変わっているかも)

0Like

Your answer might help someone💌