Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ class iBoxFactory: ProjectFactory {
]

let iBoxShareExtensionDependencies: [TargetDependency] = [
.external(name: "SnapKit")
.external(name: "SnapKit"),
.external(name: "SwiftSoup")
]

private let appInfoPlist: [String: Plist.Value] = [
Expand Down
12 changes: 12 additions & 0 deletions ShareExtension/Model/Metadata.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Metadata.swift
// iBoxShareExtension
//
// Created by ๊น€์ฐฌํฌ on 2024/03/14.
//

struct Metadata {
var title: String?
var faviconUrl: String?
var url: String?
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
import UIKit
import Social
import UniformTypeIdentifiers

import SnapKit
import SwiftSoup

@objc(CustomShareViewController)
class CustomShareViewController: UIViewController {

var backgroundView = ShareExtensionBackGroundView()
var dataURL: String = ""
var dataURL: String?

// MARK: - Life Cycle

Expand Down Expand Up @@ -64,7 +66,7 @@ class CustomShareViewController: UIViewController {
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
})
}

@objc func openURL(_ url: URL) -> Bool {
self.hideExtensionWithCompletionHandler(completion: { _ in
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
Expand Down Expand Up @@ -100,6 +102,51 @@ class CustomShareViewController: UIViewController {
}
}
}

func fetchAndParseMetadata(from url: URL, completion: @escaping (Metadata) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print("Failed to fetch data: \(String(describing: error))")
return
}

if let htmlContent = String(data: data, encoding: .utf8) {
do {
let doc: Document = try SwiftSoup.parse(htmlContent)
let title: String? = try doc.title()

let faviconSelectors = ["link[rel='shortcut icon']", "link[rel='icon']", "link[rel='apple-touch-icon']"]
var faviconUrl: String? = nil

for selector in faviconSelectors {
if let faviconLink: Element = try doc.select(selector).first() {
if var href = try? faviconLink.attr("href"), !href.isEmpty {
if href.starts(with: "/") {
href = url.scheme! + "://" + url.host! + href
} else if !href.starts(with: "http") {
href = url.scheme! + "://" + url.host! + "/" + href
}
faviconUrl = href
break
}
}
}

if faviconUrl == nil {
faviconUrl = url.scheme! + "://" + url.host! + "/favicon.ico"
}

let metadata = Metadata(title: title, faviconUrl: faviconUrl, url: url.absoluteString)

DispatchQueue.main.async {
completion(metadata)
}
} catch {
print("Failed to parse HTML: \(error.localizedDescription)")
}
}
}.resume()
}
}

extension CustomShareViewController: ShareExtensionBackGroundViewDelegate {
Expand All @@ -109,16 +156,25 @@ extension CustomShareViewController: ShareExtensionBackGroundViewDelegate {
}

func didTapOpenApp() {
let sharedData = dataURL
let url = URL(string: "iBox://\(sharedData)")!

if openURL(url) {
print("iBox ์•ฑ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์—ด๋ ธ์Šต๋‹ˆ๋‹ค.")
} else {
print("iBox ์•ฑ์„ ์—ด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
guard let sharedURL = dataURL, let url = URL(string: sharedURL) else {
print("Share extension error")
return
}

print(url)
fetchAndParseMetadata(from: url) { metadata in
let encodedTitle = metadata.title?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""
let encodedData = metadata.url?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""
let encodedFaviconUrl = metadata.faviconUrl?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""
let urlString = "iBox://url?title=\(encodedTitle)&data=\(encodedData)&faviconUrl=\(encodedFaviconUrl)"

print(urlString)
if let openUrl = URL(string: urlString) {
if self.openURL(openUrl) {
print("iBox ์•ฑ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์—ด๋ ธ์Šต๋‹ˆ๋‹ค.")
} else {
print("iBox ์•ฑ์„ ์—ด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
}
}
}
}

}
6 changes: 3 additions & 3 deletions Tuist/Dependencies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import ProjectDescription

let spm = SwiftPackageManagerDependencies([
.remote(url: "https://github.com/SnapKit/SnapKit.git", requirement: .upToNextMinor(from: "5.0.1"))
],
productTypes: ["SnapKit": .framework]
.remote(url: "https://github.com/SnapKit/SnapKit.git", requirement: .upToNextMinor(from: "5.0.1")),
.remote(url: "https://github.com/scinfu/SwiftSoup.git", requirement: .upToNextMajor(from: "2.7.1")),
], productTypes: ["SnapKit": .framework, "SwiftSoup": .framework]
)

let dependencies = Dependencies(
Expand Down
4 changes: 3 additions & 1 deletion iBox/Sources/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

print("Opened URL: \(url)")

// ์•ฑ์ด ์‹คํ–‰๋˜๊ธฐ ์ „์— url์ด ๋“ค์–ด์˜ค๋Š” ๊ฒฝ์šฐ Logic
URLdecoder.handleCustomURL(url)
}
}

Expand Down Expand Up @@ -62,6 +62,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
print("Opened URL: \(url)")

// ์•ฑ ์‹คํ–‰ ์ค‘์— url์ด ๋“ค์–ด์˜ค๋Š” ๊ฒฝ์šฐ Logic

URLdecoder.handleCustomURL(url)
}
}

Expand Down
24 changes: 24 additions & 0 deletions iBox/Sources/Shared/URLdecoder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// URLdecoder.swift
// iBoxShareExtension
//
// Created by ๊น€์ฐฌํฌ on 2024/03/14.
//

import Foundation

class URLdecoder {

static func handleCustomURL(_ url: URL) {
guard let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return }

let title = urlComponents.queryItems?.first(where: { $0.name == "title" })?.value
let data = urlComponents.queryItems?.first(where: { $0.name == "data" })?.value
let faviconUrl = urlComponents.queryItems?.first(where: { $0.name == "faviconUrl" })?.value

print("Title: \(title ?? "N/A")")
print("Data URL: \(data ?? "N/A")")
print("Favicon URL: \(faviconUrl ?? "N/A")")
}

}
10 changes: 0 additions & 10 deletions iBox/iBox.entitlements

This file was deleted.