반응형
  • 마지막으로 동적링크 만드는 방법을 알아보도록 한다.

https://firebase.google.com/docs/dynamic-links/create-manually?hl=ko

iOS 매개변수  
ibi 링크를 여는 사용할 iOS 앱의 번들 ID입니다. Firebase 콘솔의 개요 페이지에서 앱을 프로젝트에 연결해야 합니다. 동적 링크를 통해 iOS 앱을 여는 필요합니다.
ifl 앱이 설치되지 않은 경우에 열리는 링크입니다. 앱이 설치되지 않았을 App Store에서 앱을 설치하는 이외에 콘텐츠의 모바일 버전 열기, 홍보 페이지 표시 등의 다른 작업을 수행하려는 경우 매개변수를 지정합니다.
ius 앱의 번들 ID 다른 값으로 정의하면 앱의 맞춤 URL 스키마로 사용됩니다.
ipfl 앱이 설치되지 않은 경우 iPad에서 열리는 링크입니다. 앱이 설치되지 않았을 App Store에서 앱을 설치하는 이외에 콘텐츠의 버전 열기, 홍보 페이지 표시 등의 다른 작업을 수행하려면 매개변수를 지정합니다.
ipbi iPad에서 링크를 여는 사용할 iOS 앱의 번들 ID입니다. Firebase 콘솔의 개요 페이지에서 앱을 프로젝트에 연결해야 합니다.
isi 앱이 설치되지 않았다면 사용자를 App Store 보내는 사용되는 앱의 App Store ID입니다.
imv 링크를 있는 앱의 최소 버전 번호입니다. 플래그는 앱이 열렸을 앱에 전달되며 앱에서 수행할 작업을 결정해야 합니다.

 

  • 위의 매개변수를 추가하여 만들어진 동적 링크 URL은 다음과 같다.

https://appname.page.link/?link=https://com.company.appname/testlink?param=XXXXXX&ibi=com.company.appname&isi=4212345678&efr=1&ius=com.company.appname

 

  • 도메인 정보

https://appname.page.link/

  • 앱에서 열리는 링크이다. 붉은 색 링크가 앱에서 실제 수신하여 사용할 링크 정보이다.

?link=https://com.company.appname/testlink?param=XXXXXX

  • ibi는 앱의 번들 아이디를 할당하여 앱을 여는데 사용된다.

&ibi=com.company.appname

  • isi는 앱이 설치되지 않았을 경우 스토어 다운로드 페이지를 여는데 필요한 App Store ID 이다.

&isi=4212345678

  • efr은 동적링크 클릭 시 미리보기 페이지가 호출되는데 '1'로 설정할 경우 미리보기 페이지를 건너뛰고 바로 앱 호출 또는 스토어 페이지로 이동 시킨다. (Firebase 설정에서 미리보기 건너뛰기를 체크해도 적용이 안되는 경우 이 매개변수를 사용하여 해결할 수 있다)

&efr=1

  • ius는 앱의 번들 ID와 다른 값으로 정의하여 앱의 커스텀 URL 스킴으로 사용한다.
  • 여기서는 커스텀 스킴을 기본 값인 앱의 번들아이디로 사용하였다.

&ius=com.company.appname

 

  • 이상으로 firebase dynamic link(동적링크) 사용방법을 마친다.

 

 

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

2022.07.21 - [iOS/Tips] - 유니버셜 링크(Universal Links) 문제점 해결

 

 

 

반응형
블로그 이미지

SKY STORY

,
반응형
  • 이제 기본적인 설정 및 테스트를 완료하였으므로 구현 코드를 보자
// 수신되는 링크 포맷
// com.company.appname://google/link/?deep_link_id=https://com.company.appname/testlink?param=XXXXXX ... &match_message=Link is uniquely matched for this device.
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url)
    {
        self.handleIncomingDynamicLink(dynamicLink)
        return true
    }

    return true
}

// 수신되는 링크 포맷
// https://appname.page.link/?link=https://com.company.appname/testlink?param=XXXXXX ...
func application(_ application: UIApplication,
                   continue userActivity: NSUserActivity,
                   restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
{
    if let incomingURL = userActivity.webpageURL {
        print("Incoming : \(incomingURL)")
 		
        let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in
            guard error == nil else {
                print("Found an error! \(error!.localizedDescription)")
                return
            }
            if let dynamicLink = dynamicLink {
                self.handleIncomingDynamicLink(dynamicLink)
            }
        }

        if linkHandled
        {
            return true
        }
        else
        {
            if incomingURL.host == "appname.page.link" {
                guard let components = URLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
                      let queryItems = components.queryItems else { return false }
                if let link = queryItems.first(where: { $0.name == "link" })?.value {
                    print("link = \(link)")
					// https://com.company.appname/testlink?param%3D12 ...
                    return true
                }
            }
        }
    }

    return false
}

// 수신되는 링크 포맷 
// https://com.company.appname/testlink?param=@#$%@#$%^#$%^
func handleIncomingDynamicLink(_ dynamicLink: DynamicLink) {
    guard let url = dynamicLink.url else {
        print("The dynamic link object has not url.")
        return
    }
    print("url : \(url.absoluteString)")

    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
          let queryItems = components.queryItems else { return }
    if let param = queryItems.first(where: { $0.name == "param" })?.value {
        print("param = \(param)")
    }
}

 

  • 상황에 따라 호출되는 포맷이 다르므로 주의하도록 한다.

 

  • 앱이 설치되어 있고 웹링크를 통해 호출된 경우 :

https://appname.page.link/?link=https://com.company.appname/testlink?param=XXXXXX ...

 

  • 앱이 설치되어 있지 않아 스토어에서 설치된 후 실행된 경우 :

com.company.appname://google/link/?deep_link_id=https://com.company.appname/testlink?param=XXXXXX ... &match_message=Link is uniquely matched for this device.

 

 

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

2022.07.21 - [iOS/Tips] - 유니버셜 링크(Universal Links) 문제점 해결

 

 

반응형
블로그 이미지

SKY STORY

,
반응형

이제 기본 설정이 완료 됬으므로 정상적으로 설정이 됬는지 체크해 본다.

 

  • 사파리에서 AASA파일에 접근하여 정상적으로 생성되었는지 확인한다.  (App ID Prefix, Bundle ID 등을 확인)
  • 생성된 도메인의 aasa파일 접근이 웹브라우저에서 가능한지 사파리 주소창에 입력하여 테스트 해 본다.

https://YourDomainName.page.link/apple-app-site-association

아래와 같이 설정한 내용이 aasa파일에 등록되어 출력된다면 성공.

{"applinks":{"apps":[],"details":[{"appID":"6ZU18XYZJ.com.company.appName","paths":["NOT /_/*","/*"]}]}}

 

  • Xcode 프로젝트에서 Associated Domains 추가

applinks:YourDomainName.page.link

 

  • Custom URL scheme 설정한다.

 

  • URL scheme을 번들 아이디로 설정한다. (권장사항)
  • 설정된 내용 확인한다.

 

 

URL Schemes 에 번들아이디를 넣어 주도록 한다.

 

  • 이제 앱을 빌드하여 폰에 설치 한다.

 

  • 아래 주소를 아이폰 메모장에 입력하고 클릭했을 때 앱이 실행되는지 테스트 한다.

 

  • 다음 링크를 클릭했을 때 다음과 같은 페이지가 출력된다.

 

  • 위의 타이틀 이름은 프로젝트 설정의 ‘공개용 이름’이 사용되며 
  • 중간 이미지는 링크 설정에서 미리보기 이미지 URL 사용된다.

 

 

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

2022.07.21 - [iOS/Tips] - 유니버셜 링크(Universal Links) 문제점 해결

 

 

반응형
블로그 이미지

SKY STORY

,
반응형

Google Firebase 의 dynamic link는 iOS의 Universal link 기능을 기반으로 기능이 확장된 형태를 갖는다.
처음 Universal link 적용 시 웹서버 구축등 어려움을 격는 분들은 Firebase의 dynamic link 사용을 권장한다.
Firebase의 dynamic link사용 시 웹서버, 도메인 설정 및 AASA파일 작성 및 업로드 등이 자동화 되어있어 좀더 편리하다.
그럼 순서대로 사용방법을 알아 보자.

  • 프로젝트에 Podfile에 추가

 

  • Pod 인스톨 한다.

pod install

  • GoogleService-Info.plist 는 다운로드 하여 프로젝트에 추가해 준다.

 

  • Firebase 프로젝트 설정에서 App Store ID, Team ID를 설정한다.

 

  • Firebase Console 에서 동적 링크 섹션을 연다.

 

  • 구글에서 지원해주는 도메인으로 선택한다. yourdomain.page.link 선택
  • 원하는 도메인 이름을 입력한다.

 

  • 여기서는 구글지원 도메인 page.link를 사용했다.

 

  • 단축 URL 링크 설정 에서 원하는 이름을 입력한다.

ex) https://YourDomainName.page.link/testLink

 

  • 동적 링크 설정

딥 링크 URL
https://com.companyname.appname/testLink?param=1234
동적 링크 이름
My appname Deep Link

 

  • 연결할 iOS 프로젝트를 선택한다.

 

  • 안드로이드 앱이 있다면 아래 선택

 

  • 앱 미리보기 페이지 건너뛰기 체크. (테스트가 끝나면 체크하도록 하자)

 

  • 마지막으로 저장 버튼을 누른다.

 

  • 세부 정보를 클릭하면 다음과 같다.

 



 

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

2022.07.21 - [iOS/Tips] - 유니버셜 링크(Universal Links) 문제점 해결

 

반응형

'개발 > iOS' 카테고리의 다른 글

Firebase dynamic link (다이나믹 링크) (3/4)  (0) 2021.06.17
Firebase dynamic link (다이나믹 링크) (2/4)  (0) 2021.06.17
두개의 이미지 합치기  (0) 2021.03.18
시간 지연 함수  (0) 2021.03.18
경과 시간 구하기  (0) 2021.03.18
블로그 이미지

SKY STORY

,
반응형

환경 설정이 정상적으로 되어있는지 확인하려면 아래 사이트에서 가능하다.

 

Apple Search API Validation Tool 

https://search.developer.apple.com/appsearch-validation-tool

ex) 도메인이 'www.youtube.com'일 경우 검증

※ 주의 사항 : 

☞ 유니버셜링크는 앱링크 도메인이 등록된 앱이 스토어에 반영되어 있어야 하며 최도 등록시 활성화 되는데 최대 48시간의 시간이 걸릴  있다. (대부분 바로 적용 됨.)

☞ 위의 검증 사이트는 참고용으로만 사용한다. 정상적으로 동작하지만 경고를 출력하기도 한다. 예를들어 youtube.com은 정상으로 출력되나 google.com의 경우 오류가 뜬다. (참고만 할 것!)

 

 

Branch

https://branch.io/resources/aasa-validator/

Branch 와 Firebase 다이나믹 링크 비교

https://blog.branch.io/ko/branch가-firebase-다이나믹-링크를-대체할까요/

 

Apps Flyer

https://www.appsflyer.com/tools/app-links-validator/

 

Universal Link Validator

https://limitless-sierra-4673.herokuapp.com

 

yURL: Universal Links / AASA File Validator

https://yurl.chayev.com

 

 

※ 주의 사항

마지막으로, 테스트 도중 AASA파일을 수정했을 경우 앱은 이미 해당 파일이 캐싱되고 있으므로 변경된 사항이 적용되지 않았을 경우 다음과 같이 시도해 본다.

앱 삭제, 사파리의 '방문 기록 및 웹 사이트 데이터 지우기', 재부팅, 다시 앱 설치  이렇게 3번 반복!

이후 변경내용이 적용 된다. 

 

 

 

 

2021.03.16 - [iOS/Tips] - Universal Link (1/4) - 네이티브 환경설정

2021.03.16 - [iOS/Tips] - Universal Link (2/4) - 네이티브 링크 수신

2021.03.16 - [iOS/Tips] - Universal Link (3/4) - 웹서버 환경 설정

2021.03.16 - [iOS/Tips] - Universal Link (4/4) - 웹서버 환경 검증

2020.12.08 - [프로그래밍/Java Script] - Android, iOS 앱 설치여부 체크 및 스토어 이동

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

 

 

 

 

 

반응형
블로그 이미지

SKY STORY

,
반응형

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

apple-app-site-association 파일 생성 및 작성

'appID' [App ID Prefix].[Bundle ID] 작성해 준다.

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "M1ACL7W8FR.com.example.myapp",
                "paths": [ "*" ]
            }
        ]
    }
}

 

해당 파일을 도메인 루트에 복사 한다.

해당 파일이 정상적으로 접근 가능한지 테스트해 본다.

ex) 웹 브라우저에서 등록된 도메인 URL로 접근했을 때 작성된 json 정보가 출력되는지 확인한다.

https://www.youtube.com/apple-app-site-association

 

※ 주의 사항 :

☞ App ID Prefix 부분은 Team ID로 잘 못 기입하지 않도록 주의 한다. 일반적으로 이 부분은 Team ID와 동일하지만 다른 경우도 있으니 반드시 App ID Prefix를 확인하고 사용하도록 한다.

위의 AASA파일 생성 시 반드시 큰 따옴표( " )를 사용해야 한다. 또한 파일의 확장자는 붙이지 않는다.

 

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

2021.03.16 - [iOS/Tips] - Universal Link (1/4) - 네이티브 환경설정

2021.03.16 - [iOS/Tips] - Universal Link (2/4) - 네이티브 링크 수신

2021.03.16 - [iOS/Tips] - Universal Link (3/4) - 웹서버 환경 설정

2021.03.16 - [iOS/Tips] - Universal Link (4/4) - 웹서버 환경 검증

2020.12.08 - [프로그래밍/Java Script] - Android, iOS 앱 설치여부 체크 및 스토어 이동

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

 

 

반응형
블로그 이미지

SKY STORY

,
반응형

iOS Deployment Target iOS 13이상 - Swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    ...
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        guard let _ = (scene as? UIWindowScene) else { return }
        
        
        // Get URL components from the incoming user activity.
        guard let userActivity = connectionOptions.userActivities.first,
              userActivity.activityType == NSUserActivityTypeBrowsingWeb,
              let incomingURL = userActivity.webpageURL,
              let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true) else {
            return
        }
        print("url = \(incomingURL.absoluteString)")
        
        // Check for specific URL components that you need.
        guard let path = components.path,
              let params = components.queryItems else {
            return
        }
        print("path = \(path)")
        
        if let param = params.first(where: { $0.name == "param" })?.value {
            print("param = \(param)")
        } else {
            print("parsing error")
        }
    }
    ...
}

 

iOS Deployment Target iOS 13미만 - Swift

class AppDelegate: UIResponder, UIApplicationDelegate {
    ...
    func application(_ application: UIApplication,
                     continue userActivity: NSUserActivity,
                     restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
    {
        // Get URL components from the incoming user activity.
        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let incomingURL = userActivity.webpageURL,
        let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true) else {
            return false
        }
        print("url = \(incomingURL.absoluteString)")
        
        // Check for specific URL components that you need.
        guard let path = components.path,
        let params = components.queryItems else {
            return false
        }
        print("path = \(path)")
        
        if let param = params.first(where: { $0.name == "param" })?.value {
            print("param = \(param)")
            return true
        } else {
            print("parsing error")
            return false
        }
    }
    ...
}

 

iOS Deployment Target iOS 13미만 - Objective-C

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler
{
	...
	if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
		NSString *url = userActivity.webpageURL.absoluteString;
		NSLog(@"url = %@", url);
		return YES;
	}
	...
	return NO;
}

 

2021.03.16 - [iOS/Tips] - Universal Link (1/4) - 네이티브 환경설정

2021.03.16 - [iOS/Tips] - Universal Link (2/4) - 네이티브 링크 수신

2021.03.16 - [iOS/Tips] - Universal Link (3/4) - 웹서버 환경 설정

2021.03.16 - [iOS/Tips] - Universal Link (4/4) - 웹서버 환경 검증

2020.12.08 - [프로그래밍/Java Script] - Android, iOS 앱 설치여부 체크 및 스토어 이동

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

 

반응형
블로그 이미지

SKY STORY

,
반응형

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

웹에서 앱을 실행할 경우 대부분 URL scheme을 이용한다.

그런데 만약 같은 scheme id를 사용하는 앱이 2개 이상이면 

어떻게 될까?  안드로이드 운영체제에서는 앱 선택창이 떠서

원하는 앱을 실행할 수 있지만 iOS에서는 무작위로 실행된다.

(물론 내부적으로 규칙은 있겠지만... 공개되어있지 않음)

 

※ iOS 14.4.1버전 부터 타임 트릭을 이용한 앱 존재 여부 체크가

사파리가 비활성화 되도 타이머가 진행되어 앱이 존재하더라도

앱 실행 후 앱스토어 이동이 동시에 일어나는 문제가 발생한다.

 

이럴경우를 위해 URL scheme 대신 도메인 주소로 앱을 

실행할 수 있도록 한 것이 Universal Link이다.

 

유니버셜링크 환경설정 방법을 알아보자.

 

 

개발자 사이트 접속

https://developer.apple.com

 

Certificates, Identifiers & Profiles / Identifiers 선택

 

적용할 App ID 선택하고 'Associated Domains' 체크 

 

Provisioning Profile 설정이 바뀌었으므로 다시 활성화 시킨다.

 

 

Xcode에서 'Associated Domains' 을 추가

 

applinks 도메인 추가

 

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

2021.03.16 - [iOS/Tips] - Universal Link (1/4) - 네이티브 환경설정

2021.03.16 - [iOS/Tips] - Universal Link (2/4) - 네이티브 링크 수신

2021.03.16 - [iOS/Tips] - Universal Link (3/4) - 웹서버 환경 설정

2021.03.16 - [iOS/Tips] - Universal Link (4/4) - 웹서버 환경 검증

2020.12.08 - [프로그래밍/Java Script] - Android, iOS 앱 설치여부 체크 및 스토어 이동

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (1/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (2/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (3/4)

2021.06.17 - [iOS/Tips] - Firebase dynamic link (다이나믹 링크) (4/4)

 

반응형

'개발 > iOS' 카테고리의 다른 글

Universal Link (3/4) - 웹서버 환경 설정  (0) 2021.03.16
Universal Link (2/4) - 네이티브 링크 수신  (0) 2021.03.16
ARC or Non-ARC Compile Flag 설정  (0) 2021.02.05
String to CGFloat  (0) 2021.01.06
SceneDelegate 포인터 구하기  (0) 2021.01.05
블로그 이미지

SKY STORY

,