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
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d932c53
지역필터링 UI 작업중
joseph704 Aug 8, 2024
2c271ed
✨#297: Share Extension 추가
joseph704 Aug 12, 2024
8935808
🛠#297: Share Extension에서 사용할 파일들 타겟멤버쉽 추가 및 사용해야할 SDK들 의존성 추가
joseph704 Aug 12, 2024
d976f67
✨#297: 폰트들 Share Extension 타겟 멤버쉽 추가
joseph704 Aug 13, 2024
6dac975
🛠#297: Share Extension의 도입부 화면(ShareViewController) 코드 베이스 UI로 지정
joseph704 Aug 13, 2024
438cc57
🛠#297: RxGesture SPM으로 의존성 추가
joseph704 Aug 13, 2024
858da94
✨#297: Share Extensuon의 ShareViewController viewDidLoad시 가져온 위치정보를 가지…
joseph704 Aug 14, 2024
9774386
✨#297: 유튜브 뮤직앱에서 공유하기로 가져온 데이터를 파싱한 노래이름, 아티스트이름으로 음악검색 비즈니스로직 실행 및 M…
joseph704 Aug 14, 2024
6f2c6e1
✨#297: ShareViewController의 코멘트 입력창 UI/UX, MusicDropViewController와 동…
joseph704 Aug 14, 2024
98fa46d
✨#297: ShareViewController 텍스트뷰 클릭해서 키보드 올라오고 내려갈때 뷰 높이 조절
joseph704 Aug 14, 2024
81830f3
🛠#297: Share Extension 앱버전, 앱타겟과 동기화 및 CommunityGuideDetailView.swift…
joseph704 Aug 14, 2024
d137290
🛠#297: 앱 타겟, Share Extension 타겟 코드 분기 플래그 설정
joseph704 Aug 14, 2024
f56a538
✨#297: Share Extension에서 커뮤니티 가이드 UIUX 구현
joseph704 Aug 14, 2024
494c973
✨#297: Share Extension에 드랍하기 버튼 UI 추가
joseph704 Aug 14, 2024
d992f6b
🛠#297: Share Extension info.plist NSExtensionActivationSupportsWebURL…
joseph704 Aug 14, 2024
8590a26
🐛#297: ShareViewController에서 커뮤니티 가이드 툴팁 클릭 시, 드랍하기 버튼에 가려지는 현상 해결
joseph704 Aug 16, 2024
a903076
✨#297: Share Extension, 음악 재검색 UI 추가
joseph704 Aug 16, 2024
f147371
✨#297: Share ViewController의 '원하는 음악이 아닌가요' 클릭 시, 재검색 화면 나타내고 유튜브뮤직에서…
joseph704 Aug 16, 2024
f3e6367
✨#297: Share Extension의 음악 재검색 시, 음악 검색 비즈니스로직 수행 및 결과값 재검색 테이블 뷰에 나타냄
joseph704 Aug 16, 2024
c7f72b0
✨#297: Share Extension에서 재검색 화면의 원하는 테이블뷰 셀 클릭 시, 클릭한 셀의 음악 정보 이전 화면의…
joseph704 Aug 19, 2024
c8c2f43
✨#297: 두가지의 드랍하기 버튼 클릭 시, 드랍하기 비즈니스 로직 수행(성공/실패 시 UI작업은 추후에 커밋)
joseph704 Aug 19, 2024
dbf363e
✨#297: Share Extension에서 드랍하기 성공 시, 드랍 완료 화면 렌더링
joseph704 Aug 20, 2024
01b8888
♻️#297: Share Extension의 유튜브 뮤직에서 아티스트명 다른 데이터로 대체
joseph704 Aug 20, 2024
506b890
✨#297: Share Extension 화면들의 "X" 종료버튼 클릭 시, Share Extension 종료
joseph704 Aug 20, 2024
581983a
✨#297: Share Extension의 재검색 화면 백버튼 동작 추가
joseph704 Aug 20, 2024
7f9d9e6
✨#297: Share ViewController에서 다른 화면 갈때, 키보드 내리기
joseph704 Aug 20, 2024
5eae16d
✨#297: 다른 앱에서 Share Extension으로 가져온 ExtensionItem값이 없는 경우, 음악 정보 불러오지…
joseph704 Aug 20, 2024
bdbd55d
✨#297: Share Extension에서 ShareViewController -> 재검색화면 이동할때 재검색 통신 실패 …
joseph704 Aug 20, 2024
1ddc889
🐛#297: Share Extension init시 changingMusicViewClickEvent 호출되는 현상 해결
joseph704 Aug 20, 2024
7fde765
✨#297: Share Extension, 음악 정보 불러오지 못했다는 UI의 '음악 검색하기'버튼 동작 추가
joseph704 Aug 20, 2024
9815fca
✨#297: Share Extension 통신 에러 발생에 따른 에러 팝업 렌더링
joseph704 Aug 20, 2024
05566a4
✨#297: Share Extension, 다른 앱에서 Share Extension으로 가져온 ExtensionItem값이 …
joseph704 Aug 20, 2024
7f4012e
✨#297: Share Extension Alertable 주입에 따라, Share Extension에서 동작할 수 없는 로…
joseph704 Aug 20, 2024
296d7b8
🛠#297: Share Extension에서 앱으로 이동 시, 공유할 드랍된 아이템 ID 공유를 위해 Share Extens…
joseph704 Aug 22, 2024
bbfe4db
✨#297: Share Extension에서 아이템 드랍하기 API호출 시, ResponseDTO중 itemID를 앱전환 시…
joseph704 Aug 22, 2024
98efeaa
✨#297: Share Extension의 '앱에서 보기' 버튼 클릭 시, 앱으로 이동해 Share Extension에서 드…
joseph704 Aug 22, 2024
14e2f1a
refactor: 코드리뷰 반영
joseph704 Oct 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions StreetDrop/Podfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'StreetDrop' do
# platform :ios, '14.0'

def pods
pod 'NMapsMap'
pod 'Google-Mobile-Ads-SDK'
end

target 'StreetDrop' do
pods
end

target 'ShareExtension' do
pods
end
2 changes: 1 addition & 1 deletion StreetDrop/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ SPEC CHECKSUMS:
NMapsGeometry: 53c573ead66466681cf123f99f698dc8071a4b83
NMapsMap: aaa64717249b06ae82c3a3addb3a01f0e33100ab

PODFILE CHECKSUM: c1edcf3d49503875acf5f6e7bfd364191c925046
PODFILE CHECKSUM: a8c0902adb23412ed3e2bbd632c3c7f7846b9405

COCOAPODS: 1.15.2
35 changes: 35 additions & 0 deletions StreetDrop/ShareExtension/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-7717835511859758~1784783942</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ShareViewController</string>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.share-services</string>
</dict>
<key>UIAppFonts</key>
<array>
<string>Pretendard-Black.otf</string>
<string>Pretendard-Bold.otf</string>
<string>Pretendard-ExtraBold.otf</string>
<string>Pretendard-ExtraLight.otf</string>
<string>Pretendard-Light.otf</string>
<string>Pretendard-Medium.otf</string>
<string>Pretendard-Regular.otf</string>
<string>Pretendard-SemiBold.otf</string>
<string>Pretendard-Thin.otf</string>
</array>
</dict>
</plist>
10 changes: 10 additions & 0 deletions StreetDrop/ShareExtension/ShareExtension.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.depromeet.StreetDrop</string>
</array>
</dict>
</plist>
269 changes: 269 additions & 0 deletions StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
//
// DropDoneView.swift
// ShareExtension
//
// Created by 차요셉 on 8/19/24.
//

import UIKit

import RxSwift
import RxRelay
import Kingfisher
import SnapKit

final class DropDoneView: UIView {
// View -> ViewController
private let exitButtonEventRelay: PublishRelay<Void> = .init()
var exitButtonEvent: Observable<Void> {
exitButtonEventRelay.asObservable()
}
private let viewOnAppButtonEventRelay: PublishRelay<Void> = .init()
var viewOnAppButtonEvent: Observable<Void> {
viewOnAppButtonEventRelay.asObservable()
}

private let droppedMusic: Music
private let droppedAddress: String
private let droppedComment: String
private let disposeBag: DisposeBag = .init()

init(
droppedMusic: Music,
droppedAddress: String,
droppedComment: String
) {
self.droppedMusic = droppedMusic
self.droppedAddress = droppedAddress
self.droppedComment = droppedComment
super.init(frame: .zero)
bindAction()
configureUI()
}

@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private let dropDoneTitleLabel: UILabel = {
let label: UILabel = .init()
label.text = "드랍 완료!"
label.font = .pretendard(size: 18, weight: 700)
label.textColor = .white
label.setLineHeight(lineHeight: 28)

return label
}()

private let exitButton: UIButton = {
let button: UIButton = .init()
button.setImage(.init(named: "exit"), for: .normal)

return button
}()

private let contentContainerView: UIView = {
let view: UIView = .init()
view.backgroundColor = .gray700
view.layer.cornerRadius = 20

return view
}()

private lazy var albumImageView: UIImageView = {
let imageView: UIImageView = .init()
imageView.layer.cornerRadius = 8
imageView.layer.borderWidth = 1
imageView.layer.borderColor = UIColor.white.withAlphaComponent(0.05).cgColor
imageView.layer.masksToBounds = true

imageView.kf.setImage(with: URL(string: droppedMusic.albumImage))

return imageView
}()

private lazy var songNameLabel: UILabel = {
let label: UILabel = .init()
label.text = droppedMusic.songName
label.font = .pretendard(size: 14, weight: 500)
label.textColor = .white
label.setLineHeight(lineHeight: 20)

return label
}()

private lazy var artistNameLabel: UILabel = {
let label: UILabel = .init()
label.text = droppedMusic.artistName
label.textColor = .gray200
label.font = .pretendard(size: 12, weight: 400)
label.setLineHeight(lineHeight: 16)

return label
}()

private let middleLine: UIView = {
let view: UIView = .init()
view.backgroundColor = .gray600

return view
}()

private lazy var commentLabel: UILabel = {
let label: UILabel = .init()
label.text = droppedComment
label.font = .pretendard(size: 14, weight: 400)
label.textColor = .white
label.numberOfLines = 0
label.setLineHeight(lineHeight: 20)

return label
}()

private let locationImageView: UIImageView = {
let imageView: UIImageView = .init(image: .init(named: "share-extension-location"))

return imageView
}()

private lazy var addressLabel: UILabel = {
let label: UILabel = .init()
label.text = droppedAddress
label.font = .pretendard(size: 12, weight: 400)
label.textColor = .primary400
label.setLineHeight(lineHeight: 16)

return label
}()

private let viewOnAppButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("앱에서 보기", for: .normal)
button.setTitleColor(.gray900, for: .normal)
button.titleLabel?.font = .pretendard(size: 16, weight: 700)
button.layer.cornerRadius = 12
button.backgroundColor = .primary400

return button
}()
}

private extension DropDoneView {
func bindAction() {
exitButton.rx.tap
.bind(to: exitButtonEventRelay)
.disposed(by: disposeBag)

viewOnAppButton.rx.tap
.bind(to: viewOnAppButtonEventRelay)
.disposed(by: disposeBag)
}

func configureUI() {
layer.cornerRadius = 20
layer.borderWidth = 1
layer.borderColor = UIColor.gray600.cgColor
backgroundColor = .gray800

[
dropDoneTitleLabel,
exitButton,
contentContainerView,
viewOnAppButton
].forEach {
addSubview($0)
}

[
albumImageView,
songNameLabel,
artistNameLabel,
middleLine,
commentLabel,
locationImageView,
addressLabel
].forEach {
contentContainerView.addSubview($0)
}

dropDoneTitleLabel.snp.makeConstraints {
$0.top.equalToSuperview().inset(22)
$0.leading.equalToSuperview().inset(24)
$0.height.equalTo(28)
}

exitButton.snp.makeConstraints {
$0.width.equalTo(44)
$0.height.equalTo(32)
$0.top.equalToSuperview().inset(20)
$0.trailing.equalToSuperview().inset(24)
}

var contentContainerViewHeightConstraint: Constraint?
contentContainerView.snp.makeConstraints {
contentContainerViewHeightConstraint = $0.height.equalTo(0).constraint
$0.top.equalTo(dropDoneTitleLabel.snp.bottom).offset(10)
$0.horizontalEdges.equalToSuperview().inset(24)
}

albumImageView.snp.makeConstraints {
$0.width.height.equalTo(48)
$0.top.equalToSuperview().inset(16)
$0.leading.equalToSuperview().inset(20)
}

songNameLabel.snp.makeConstraints {
$0.height.equalTo(20)
$0.top.equalToSuperview().inset(20)
$0.leading.equalTo(albumImageView.snp.trailing).offset(8)
}

artistNameLabel.snp.makeConstraints {
$0.height.equalTo(16)
$0.top.equalTo(songNameLabel.snp.bottom).offset(2)
$0.leading.equalTo(albumImageView.snp.trailing).offset(8)
}

middleLine.snp.makeConstraints {
$0.height.equalTo(1)
$0.top.equalTo(albumImageView.snp.bottom).offset(16)
$0.horizontalEdges.equalToSuperview().inset(20)
}

commentLabel.snp.makeConstraints {
$0.top.equalTo(middleLine.snp.bottom).offset(16)
$0.horizontalEdges.equalToSuperview().inset(20)
}

locationImageView.snp.makeConstraints {
$0.width.equalTo(13)
$0.height.equalTo(16)
$0.top.equalTo(commentLabel.snp.bottom).offset(10)
$0.leading.equalToSuperview().inset(20)
}

addressLabel.snp.makeConstraints {
$0.height.equalTo(16)
$0.top.equalTo(locationImageView)
$0.leading.equalTo(locationImageView.snp.trailing)
}

viewOnAppButton.snp.makeConstraints {
$0.height.equalTo(56)
$0.horizontalEdges.equalToSuperview().inset(24)
$0.bottom.equalToSuperview().inset(48)
}

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인지 상수로 선언되어 있으면 더 좋겠네요..! (유지보수를 위하여,,)

contentContainerViewHeightConstraint?.update(
offset: contentContainerHeight
)

snp.makeConstraints {
$0.height.equalTo(60 + contentContainerHeight + 132)
}
}
}
Loading