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

✨ 다른 앱에서 스트릿드랍으로 공유하는 Share Extension 기능 추가 #300

Open
wants to merge 37 commits into
base: feature/region-filtering
Choose a base branch
from

Conversation

joseph704
Copy link
Member

@joseph704 joseph704 commented Aug 22, 2024

📌 배경

close #297

내용

  • 유튜브 뮤직앱에서 음악 공유 -> 스트릿드랍 아이콘 클릭 시, 공유된 음악에 대한 Share Extension만의 드랍하기 프로세스 진행
  • Share Extensuon의 ShareViewController viewDidLoad시 가져온 위치정보를 가지고 서버통신을 통해 주소 찍어줌
    • 위치정보는 기존 앱과 동일하게 CoreLocation iOS 내부라이브러리 사용
  • 유튜브 뮤직에서 넘겨주는 음악 정보 파싱, 파싱한 음악이름과 아티스트 이름을 통해 프로세스 진행
  • 첫번쨰 화면의 '원하는 음악이 아닌가요' 클릭 시, 재검색 비즈니스 로직 제공
  • 여러 에러의 예외처리를 팝업으로 띄움
  • 드랍 UI, 재검색 UI, 드랍완료 UI, 공유하기 error UI 모두 UIView로써 ShareViewController가 의존하도록 함.
  • 대부분의 UIView에서 이벤트가 일어나면 ShareViewController로 단방향적으로 이벤트를 전달하도록 함.
  • Share Extension에서 앱으로 이동 시, 공유할 드랍된 아이템 ID 공유를 위해 Share Extension과 App간의 App Groups를 설정
  • Share Extension의 '앱에서 보기' 버튼 클릭 시, 앱으로 이동해 Share Extension에서 드랍한 아이템에 대한 커뮤니티 Scene에서 렌더링
    • 메인 Scene ViewDidAppear 또는 Bakcground -> Foreground 전환 시 커뮤니티 Scene 렌더링

테스트 방법 (optional)

  • 유튜브 뮤직앱에서 원하는 음악 공유하기 누르고, 스트릿 드랍 아이콘 클릭
  • 유튜브 뮤직 뿐만 아니라, 다른 앱에서도 클릭하면 예외처리에 의한 공유하기 error UI/UX 테스트 가능

스크린샷 (optional)

RPReplay_Final1724291345-2.MP4
RPReplay_Final1724291387-2.MP4

…고 서버통신을 통해 주소 찍어줌

- 그 외 몇가지 UI들만 추가
- Share Extension에서는 UIApplication.shared.open(url) 사용 불가능해서 SFSafariViewController로 노션페이지 띄움
- 기존 드랍하기 버튼 이외에, 텍스트뷰 클릭해서 키보드 올라올때, 키보드 바로위에 드랍하기 버튼 추가
…WithMaxCount 키값 1로 설정해서 한 번에 하나의 웹 URL만 수락하도록 함

- NSExtensionActivationSupportsWebURLWithMaxCount: 이 키는 확장이 웹 URL을 수락하고 처리할 수 있다는 것을 나타냄. 값은 최대 몇 개의 웹 URL을 한 번에 지원할 수 있는지를 나타내는 정수로 설정
- 기존 데이터는 뒤에 "- TOPIC' 접미어가 붙어 검색 정확도가 떨어졌음
- 원래 changingMusicView 클릭 할때만 이벤트 발생해야함
- '음악 검색하기'버튼 클릭 시, 빈 테이블뷰의 재검색 화면으로 이동
- 정상 동작을 위한 재기동을 위해 팝업 확인 버튼 클릭 시, Share Extension 종료
…없는 경우(음악 정보 못가져온 경우) 딜레이없이 빠르게 관련 UI 렌더링
…랍한 아이템에 대한 커뮤니티 Scene에서 렌더링

- Share Extension에서 드랍한 아이템 ID, UserDefaults에 저장 및 메인 Scene ViewDidAppear 또는 Bakcground -> Foreground 전환 시 커뮤니티 Scene 렌더링
@joseph704 joseph704 added the Request 요청 사항 label Aug 22, 2024
@joseph704 joseph704 self-assigned this Aug 22, 2024

layoutIfNeeded()

let contentContainerHeight = 16 + 48 + 33 + commentLabel.actualNumberOfLines() * 20 + 46
Copy link
Collaborator

Choose a reason for hiding this comment

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

어떤 컴포넌트의 height인지 상수로 선언되어 있으면 더 좋겠네요..! (유지보수를 위하여,,)

Copy link
Collaborator

@thoonk thoonk left a comment

Choose a reason for hiding this comment

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

고생하셨습니다 요셉님~~!

Comment on lines 103 to 107
private lazy var searchCancelView: UIView = {
let view: UIView = .init()

return view
}()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
private lazy var searchCancelView: UIView = {
let view: UIView = .init()
return view
}()
private lazy var searchCancelView: UIView = .init()

Copy link
Collaborator

Choose a reason for hiding this comment

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

lazy 도 빼도 될거같네용

Comment on lines 33 to 37
private let warningImageView: UIImageView = {
let imageView: UIImageView = .init(image: .init(named: "warning"))

return imageView
}()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
private let warningImageView: UIImageView = {
let imageView: UIImageView = .init(image: .init(named: "warning"))
return imageView
}()
private let warningImageView: UIImageView = .init(image: .init(named: "warning"))

func bindAction() {
searchTextField.rx.text.orEmpty
.filter { $0.isEmpty }
.map { _ in }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
.map { _ in }


sceneDelegate.navigateToCommunity(with: shareExtensionDroppedItemID)
sharedDefaults.removeObject(forKey: "ShareExtensionDroppedItemID")
sharedDefaults.synchronize()
Copy link
Collaborator

Choose a reason for hiding this comment

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

synchronize() 메서드는 공식 레퍼런스에서도 사용하지 않는 것을 권장하고 있습니다!
참고

Copy link
Collaborator

@wendoei wendoei left a comment

Choose a reason for hiding this comment

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

고생하셨습니다~!!

Comment on lines 103 to 107
private lazy var searchCancelView: UIView = {
let view: UIView = .init()

return view
}()
Copy link
Collaborator

Choose a reason for hiding this comment

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

lazy 도 빼도 될거같네용

Comment on lines 29 to 31
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

별도 작업을 하지 않아서 제거해도 될거같네용~


communityGuideButton.rx.tap
.bind { [weak self] in
guard let self = self else { return }
Copy link
Collaborator

Choose a reason for hiding this comment

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

옵셔널 제거 단축 syntax 로 써도 될거같아요~!
https://github.com/swiftlang/swift-evolution/blob/main/proposals/0345-if-let-shorthand.md

Suggested change
guard let self = self else { return }
guard let self else { return }

Comment on lines 99 to 101
} onFailure: { owner, error in

}
Copy link
Collaborator

Choose a reason for hiding this comment

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

제거해도될거같네용~


func navigateToCommunity(with itemID: Int) {
let sceneDelegate = UIApplication.shared.connectedScenes
.first!.delegate as? SceneDelegate
Copy link
Collaborator

Choose a reason for hiding this comment

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

지금도 type 이 SceneDelegate? 라서 first? 로 써도 될거같아요~

let sceneDelegate = UIApplication.shared.connectedScenes
.first!.delegate as? SceneDelegate

if let navigationView = topViewController(base: sceneDelegate?.window!.rootViewController)?
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기도 window? 해도 될거같네용~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Request 요청 사항
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants