Files
ratebubble/ios/Ratebubble/ShareExtension/ShareViewController.swift

108 lines
4.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import UIKit
import UniformTypeIdentifiers
final class ShareViewController: UIViewController {
private let statusLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
Task { await handleIncomingShare() }
}
private func setupUI() {
view.backgroundColor = .systemBackground
statusLabel.translatesAutoresizingMaskIntoConstraints = false
statusLabel.textAlignment = .center
statusLabel.numberOfLines = 0
statusLabel.text = "Paylaşılan bağlantı alınıyor..."
view.addSubview(statusLabel)
NSLayoutConstraint.activate([
statusLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
statusLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
statusLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
@MainActor
private func updateStatus(_ text: String) {
statusLabel.text = text
}
private func handleIncomingShare() async {
guard let item = extensionContext?.inputItems.first as? NSExtensionItem,
let providers = item.attachments else {
updateStatus("Paylaşılan içerik okunamadı.")
return
}
for provider in providers {
if let extracted = await extractURL(from: provider), isSupportedStreamingURL(extracted) {
SharedPayloadStore.saveIncomingURL(extracted.absoluteString)
updateStatus("Bağlantı alındı, uygulama açılıyor...")
openHostApp()
return
}
}
updateStatus("Geçerli bir Netflix/Prime Video linki bulunamadı.")
}
private func extractURL(from provider: NSItemProvider) async -> URL? {
if provider.hasItemConformingToTypeIdentifier(UTType.url.identifier) {
return await withCheckedContinuation { continuation in
provider.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil) { item, _ in
continuation.resume(returning: item as? URL)
}
}
}
if provider.hasItemConformingToTypeIdentifier(UTType.text.identifier) {
return await withCheckedContinuation { continuation in
provider.loadItem(forTypeIdentifier: UTType.text.identifier, options: nil) { item, _ in
if let raw = item as? String, let url = URL(string: raw.trimmingCharacters(in: .whitespacesAndNewlines)) {
continuation.resume(returning: url)
return
}
continuation.resume(returning: nil)
}
}
}
return nil
}
private func isSupportedStreamingURL(_ url: URL) -> Bool {
let host = url.host?.lowercased() ?? ""
let netflixHosts = ["www.netflix.com", "netflix.com", "www.netflix.com.tr", "netflix.com.tr"]
let primeHosts = ["www.primevideo.com", "primevideo.com", "www.amazon.com", "amazon.com"]
let isNetflix = netflixHosts.contains(host)
let isPrime = primeHosts.contains(host)
guard isNetflix || isPrime else { return false }
let path = url.path.lowercased()
if path.contains("/title/") || path.contains("/watch/") || path.contains("/detail/") {
return true
}
// Some share links can be shortened/redirect style without a canonical path.
return !path.isEmpty && path != "/"
}
private func openHostApp() {
guard let url = URL(string: "\(SharedConfig.appURLScheme)://ingest") else {
extensionContext?.completeRequest(returningItems: nil)
return
}
extensionContext?.open(url) { success in
// If opening succeeded, the system should transition to the host app.
// Completing the extension request immediately can bounce back to the source app.
guard !success else { return }
self.extensionContext?.completeRequest(returningItems: nil)
}
}
}