-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
feat: share extension 추가/#40
- Loading branch information
Showing
6 changed files
with
361 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// | ||
// ShareViewController.swift | ||
// iBoxWebShareExtension | ||
// | ||
// Created by Chan on 2/8/24. | ||
// | ||
|
||
import UIKit | ||
import Social | ||
import UniformTypeIdentifiers | ||
import SnapKit | ||
|
||
@objc(CustomShareViewController) | ||
class CustomShareViewController: UIViewController { | ||
|
||
var backgroundView = ShareExtensionBackGroundView() | ||
var dataURL: String = "" | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
configureUI() | ||
extractSharedURL() | ||
} | ||
|
||
func configureUI() { | ||
self.view.addSubview(backgroundView) | ||
backgroundView.delegate = self | ||
backgroundView.snp.makeConstraints { make in | ||
make.trailing.leading.equalToSuperview().inset(20) | ||
make.center.equalToSuperview() | ||
make.height.equalTo(200) | ||
} | ||
} | ||
|
||
func getAppGroupUserDefaults() { | ||
let defaults = UserDefaults(suiteName: "group.com.iBox") | ||
if let data = defaults?.string(forKey: "share") { | ||
print("ShareViewController: URL 가져오기: \(data)") | ||
} | ||
} | ||
|
||
func hideExtensionWithCompletionHandler(completion: @escaping (Bool) -> Void) { | ||
UIView.animate(withDuration: 0.3, animations: { | ||
self.navigationController?.view.transform = CGAffineTransform(translationX: 0, y:self.navigationController!.view.frame.size.height) | ||
}, completion: completion) | ||
} | ||
|
||
// MARK: IBAction | ||
|
||
@IBAction func cancel() { | ||
self.hideExtensionWithCompletionHandler(completion: { _ in | ||
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) | ||
}) | ||
} | ||
|
||
@IBAction func save() { | ||
if dataURL != "" { | ||
let sharedData = dataURL | ||
print(sharedData) | ||
} else { | ||
print("저장에 실패하였습니다.") | ||
} | ||
|
||
self.hideExtensionWithCompletionHandler(completion: { _ in | ||
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) | ||
}) | ||
} | ||
|
||
|
||
@objc func openURL(_ url: URL) -> Bool { | ||
self.hideExtensionWithCompletionHandler(completion: { _ in | ||
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) | ||
}) | ||
|
||
var responder: UIResponder? = self | ||
while responder != nil { | ||
if let application = responder as? UIApplication { | ||
return application.perform(#selector(openURL(_:)), with: url) != nil | ||
} | ||
responder = responder?.next | ||
} | ||
return false | ||
} | ||
|
||
func extractSharedURL() { | ||
guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else { return } | ||
|
||
for attachment in extensionItem.attachments ?? [] { | ||
if attachment.hasItemConformingToTypeIdentifier(UTType.url.identifier) { | ||
attachment.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil) { [weak self] (data, error) in | ||
DispatchQueue.main.async { | ||
if let url = data as? URL, error == nil { | ||
self?.dataURL = url.absoluteString | ||
self?.backgroundView.updateLinkLabel(with: url.absoluteString) | ||
print("Shared URL: \(url.absoluteString)") | ||
} else { | ||
print("Failed to retrieve URL: \(String(describing: error))") | ||
} | ||
} | ||
} | ||
break | ||
} | ||
} | ||
} | ||
} | ||
|
||
extension CustomShareViewController: ShareExtensionBackGroundViewDelegate { | ||
|
||
func didTapCancel() { | ||
cancel() | ||
} | ||
|
||
func didTapSave() { | ||
save() | ||
} | ||
|
||
func didTapOpenApp() { | ||
let sharedData = dataURL | ||
let url = URL(string: "iBox://\(sharedData)")! | ||
|
||
if openURL(url) { | ||
print("iBox 앱이 성공적으로 열렸습니다.") | ||
} else { | ||
print("iBox 앱을 열 수 없습니다.") | ||
} | ||
|
||
print(url) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
// | ||
// BackGroundView.swift | ||
// iBox | ||
// | ||
// Created by Chan on 2/19/24. | ||
// | ||
|
||
import UIKit | ||
|
||
import SnapKit | ||
|
||
protocol ShareExtensionBackGroundViewDelegate: AnyObject { | ||
func didTapCancel() | ||
func didTapSave() | ||
func didTapOpenApp() | ||
} | ||
|
||
class ShareExtensionBackGroundView: UIView { | ||
|
||
// MARK: - Properties | ||
|
||
weak var delegate: ShareExtensionBackGroundViewDelegate? | ||
|
||
// MARK: - UI Components | ||
|
||
lazy var label: UILabel = { | ||
let label = UILabel() | ||
label.text = "이 링크를 iBox 앱에서 여시겠습니까?" | ||
label.font = .systemFont(ofSize: 17) | ||
label.textColor = .label | ||
return label | ||
}() | ||
|
||
lazy var linkLabel: UILabel = { | ||
let label = UILabel() | ||
label.textColor = .label | ||
label.numberOfLines = 3 | ||
label.lineBreakMode = .byTruncatingTail | ||
return label | ||
}() | ||
|
||
lazy var cancelButton: UIButton = { | ||
let button = UIButton() | ||
button.configuration = .plain() | ||
button.configuration?.attributedTitle = .init( | ||
"Cancel", | ||
attributes: .init([.font: UIFont.systemFont(ofSize: 14)]) | ||
) | ||
return button | ||
}() | ||
|
||
lazy var saveButton: UIButton = { | ||
let button = UIButton() | ||
button.configuration = .plain() | ||
button.configuration?.attributedTitle = .init( | ||
"Save", | ||
attributes: .init([.font: UIFont.boldSystemFont(ofSize: 14)]) | ||
) | ||
return button | ||
}() | ||
|
||
lazy var openAppButton: UIButton = { | ||
let button = UIButton() | ||
button.configuration = .plain() | ||
button.configuration?.attributedTitle = .init( | ||
"Open", | ||
attributes: .init([.font: UIFont.boldSystemFont(ofSize: 14)]) | ||
) | ||
return button | ||
}() | ||
|
||
// MARK: - Initializer | ||
|
||
override init(frame: CGRect) { | ||
super.init(frame: frame) | ||
|
||
setupHierarchy() | ||
setupLayout() | ||
setupButtonAction() | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
// MARK: - Setup Methods | ||
|
||
private func setupHierarchy() { | ||
addSubview(label) | ||
addSubview(linkLabel) | ||
addSubview(cancelButton) | ||
addSubview(saveButton) | ||
addSubview(openAppButton) | ||
} | ||
|
||
private func setupLayout() { | ||
backgroundColor = .systemBackground | ||
clipsToBounds = true | ||
layer.cornerRadius = 10 | ||
|
||
label.snp.makeConstraints { | ||
$0.top.leading.equalToSuperview().inset(20) | ||
} | ||
|
||
linkLabel.snp.makeConstraints { | ||
$0.top.equalTo(label.snp.bottom).offset(10) | ||
$0.leading.trailing.equalToSuperview().inset(20) | ||
} | ||
|
||
cancelButton.snp.makeConstraints { | ||
$0.trailing.equalTo(saveButton.snp.leading).offset(-20) | ||
$0.centerY.equalTo(openAppButton.snp.centerY) | ||
} | ||
|
||
saveButton.snp.makeConstraints { | ||
$0.trailing.equalTo(openAppButton.snp.leading).offset(-20) | ||
$0.centerY.equalTo(openAppButton.snp.centerY) | ||
} | ||
|
||
openAppButton.snp.makeConstraints { | ||
$0.trailing.bottom.equalToSuperview().inset(20) | ||
} | ||
} | ||
|
||
private func setupButtonAction() { | ||
cancelButton.addTarget(self, action: #selector(cancelButtonTapped), for: .touchUpInside) | ||
saveButton.addTarget(self, action: #selector(saveButtonTapped), for: .touchUpInside) | ||
openAppButton.addTarget(self, action: #selector(openAppButtonTapped), for: .touchUpInside) | ||
} | ||
|
||
func updateLinkLabel(with text: String) { | ||
linkLabel.text = text | ||
} | ||
|
||
// MARK: - Actions | ||
|
||
@objc func cancelButtonTapped() { | ||
delegate?.didTapCancel() | ||
} | ||
|
||
@objc func saveButtonTapped() { | ||
delegate?.didTapSave() | ||
} | ||
|
||
@objc func openAppButtonTapped() { | ||
delegate?.didTapOpenApp() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.