Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 앱 내에서 동적링크 생성 (#338) #341

Merged
merged 22 commits into from
Jan 8, 2023
Merged

Conversation

hyun99999
Copy link
Member

@hyun99999 hyun99999 commented Jan 5, 2023

🌴 PR 요약

🌱 작업한 브랜치

🌱 작업한 내용

  • 본 풀리퀘는 앱 내에서 동적링크를 생성하고, QR code 이미지를 생성하고, 올바르게 앱 내의 카메라를 이용해서 조회하는데까지 구현하였습니다.
  • 새롭게 만든 동적 링크를 파싱해서 cardID 파라미터를 수집해서 명함을 조회하였습니다.
  • 동적링크를 줄이지 않으면 url 이 너무 길어져서 아래처럼 환 공포증을 유발할 수 있습니다..

  • 그래서 짧은 동적 링크를 사용하다보니 네트워크 통신을 하게되었습니다. 그래서 qr code 를 생성할 때 약간의 딜레이가 생겼습니다. qa 를 거쳐보고 불편하다면 로딩하고 있다는 표시를 넣어보도록 해용.
  • feat: QR코드 메시지 변경하여 기본 카메라에서도 접근할 수 있도록 구현 #334 이슈는 기본 카메라에서 qr code 를 인식하는 것이 구현되었기 때문에 pr 이 머지되면 같이 닫겠습니다.

🚨 참고사항

  • associated domain 을 추가했는데도 앱이 설치되었을 때 앱이 아닌 앱스토어로 보내고 있습니다. 이는 동적 링크를 잘 못 생성했을 가능성이 있기 때문에 다른 이슈를 파서 진행하겠습니다.
  • URL Scheme 를 설정해주지 않아서 열리지 않았는줄 알았는데 동적 링크는 이미 딥링크 기능을 url 에서 지원하므로, 딱히 설정은 필요없었습니다. 대신, firebase 에서 iOS 앱을 등록할 때 팀 ID 가 누락되었고, 이를 해결해주고 몇 분지나서 유효한 동적링크로 작동하였습니다.
https://itznada.page.link/apple-app-site-association
// 위의 url 을 확인해서 details 가 채워지면 유효한 동적 링크라고 합니다.

동적 링크를 만드는 과정은 아래 노션에 첨부하겠습니다.
https://www.notion.so/iOS-Firebase-Dynamic-Link-7d473b325ff94b889285cf1871c784e9

  • 앱 미설치시
RPReplay_Final1672927791.MP4
  • 앱 설치시
RPReplay_Final1672927773.MP4
  • 앱이 열리게 되면 그때, todo 주석에 써놓은 로직대로 홈뷰에서 명함을 조회하게 할 생각입니다.

프로젝트에는 주석이 불필요할거 같아서 여기에 주석을 달아두었습니다!

  • 동적 링크를 사용하여 qr code 이미지 생성 코드 주석.
// QR Code 이미지 생성하는 메서드.
private func setQRImage() {
    let frame = CGRect(origin: .zero, size: qrImage.frame.size)
    let qrcode = QRCodeView(frame: frame)
    generateDynamicLink(with: cardDataModel?.cardID ?? "") { dynamicLink in
    
        // 🚨
        // 짧은 동적 링크를 만들때 네트워크 요청으로 인해 completion handler 를 사용하고 있다.
        // 이 작업이 끝나기를 기다린 후에 짧은 동적 링크를 사용할 수 있기 때문에,
        // @escaping closure 를 사용하여 generateDynamicLink(with:) 메서드의 작업이 끝난 후에 QR Code 이미지 생성 작업을 하도록 하였다.

        // 👉 QRCodeView 커스텀 클래스의 QR Code 이미지를 만드는 커스텀 메서드이다.
        qrcode.generateCode(dynamicLink)
        self.qrImage.addSubview(qrcode)
    }
}

private func generateDynamicLink(with cardID: String, completion: @escaping ((String) -> Void)) {

    // ✅ 링크에 cardID 를 파라미터로 추가. -> SceneDelegate 에서 cardID 를 받아와서 사용.
    guard let link = URL(string: "https://www.example.com/my-page" + "/?id=" + cardID),
          let bundleID = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String else { return }
    let domainURLPrefix = "https://(...).page.link"
    
    // ✅ Dynamic Link parameter 설정.
    
    // link : 앱이 열게될 링크. 데스크탑 웹 브라우저 환경에서 동적링크를 열게되면 해당 링크가 열립니다.
    // domainURLPrefix : Firebase 콘솔에서 설정한 Dynamic Link URL prefix 이다.
    let linkBuilder = DynamicLinkComponents(link: link, domainURIPrefix: domainURLPrefix)
    
    linkBuilder?.iOSParameters = DynamicLinkIOSParameters(bundleID: bundleID)
    
    // ✅ Apple Connect Store 에서 확인할 수 있는 ID 이다. 앱이 설치되지 않은 경우에 사용자를 App Store 로 보내는데 사용한다.
    linkBuilder?.iOSParameters?.appStoreID = "..."
    
    // ✅ true 로 설정하여 app preview page 를 건너띄고 app 또는 app store 로 리다이렉트.
    linkBuilder?.navigationInfoParameters = DynamicLinkNavigationInfoParameters()
    linkBuilder?.navigationInfoParameters?.isForcedRedirectEnabled = true
    
    var dynamicLink: String = ""
    
    // ✅ 고유한 suffix 생성.
    linkBuilder?.options = DynamicLinkComponentsOptions()
    linkBuilder?.options?.pathLength = .short
    
    // ✅ 짧은 DynamicLink 로 변경.
    // 짧은 동적 링크를 만들기 위해서는 네트워크 요청이 필요하므로 링크를 바로 반환하는 것이 아니라 요청이 완료된 후에 호출되는 completion handler 를 사용한다.
    linkBuilder?.shorten { url, warnings, error in
        if let url {
            dynamicLink = "\(url)"
        }

        // ✅ 현재 메서드의 작업이 끝난 후 즉, 짧은 동적 링크가 만들어진 후에 completion handler 실행.
        completion(dynamicLink)
    }
    
// ✅ 긴 동적 링크를 다음과 같이 그대로 사용할 수 있다. 하지만, 프로젝트에서는 QR Code 이미지가 너무 복잡해져서 보기 좋지 않았다. 그래서 짧은 동적 코드로 생성하였다.
//        if let url = linkBuilder?.url {
//            dynamicLink = "\(url)"
//        }
}
  • cardID 를 파싱하는 함수.
// MARK: - Extensions

extension SceneDelegate {
    private func handleDynamicLink(_ dynamicLink: DynamicLink?) -> String? {
        guard let dynamicLink = dynamicLink,
              // 앱으로 전달되는 url 을 얻을 수 있다.
              let link = dynamicLink.url else { return nil }
        
        // resolvingAgainstBaseURL : URL 구문을 분석하기 전에 URl 에 대해 확인하는지 여부를 제어.
        // true 이고, url parameter 에 상대적인 URl 이 포함되어 있다면 absoluteURL 메서드를 호출해서 original URl 에 대해서 확인합니다. 그렇지 않으면, 문자열 부분이 자체적으로 사용됩니다.
        let queryItems = URLComponents(url: link, resolvingAgainstBaseURL: true)?.queryItems
        
        let cardID = queryItems?.filter { $0.name == "cardID" }.first?.value
        
        return cardID
    }
}

📸 스크린샷

기능 스크린샷
앱 내에서 명함조회

📮 관련 이슈

- 충분히 함수명으로 역할을 알 수 있기 때문에 불필요한 주석이라고 판단했습니다.
- SelectBirthBottomViewController, CardShareBottomSheetViewController 해당하는 수정
@hyun99999 hyun99999 added Hyungyu 🐯 현규 교수님 작업 Feat 새로운 기능 구현 labels Jan 5, 2023
@hyun99999 hyun99999 requested a review from dlwns33 January 5, 2023 06:49
@hyun99999 hyun99999 self-assigned this Jan 5, 2023
@hyun99999
Copy link
Member Author

그리고 시뮬에서는 라이트모드일때 qr 이 안보이고 다크모드에서 보이네요..
그런데 실기기에서는 둘다 보여여(위에가 실기기 캡처)
준쌤한테도 동일한지 한번 체크 부탁드립니당

@hyun99999 hyun99999 changed the title feat: 앱 내에서 동적링크 생성 (#388) feat: 앱 내에서 동적링크 생성 (#338) Jan 5, 2023
- 동적 링크라서 딥링크는 이미 지원하기 때문에 굳이 URl Scheme 설정해줄 필요가 없었다. 파이어베이스 iOS 앱에 팀ID 를 설정하고 시간이 지나면서 동적 링크가 유효해져서 정상 작동을 확인하였다.
Copy link
Member

@dlwns33 dlwns33 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다! 파이어베이스로 동적링크를 생성하는군요.. 하나 또 배워갑니다🙇‍♀️

@hyun99999 hyun99999 merged commit 9ddaaf4 into develop Jan 8, 2023
@hyun99999 hyun99999 deleted the feature/#338 branch January 8, 2023 10:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feat 새로운 기능 구현 Hyungyu 🐯 현규 교수님 작업
Projects
None yet
2 participants