Swift:拖放,保存 google 张图片中的 url 张图片

Swift: Drag and Drop, save url of image from google images

我正在尝试创建一个由集合视图组成的应用程序,其中拖有图像。

我正在双显示器中打开 google 个图像,搜索 "seals" 并将印章的第一张图像拖到我的应用 viewcontroller 上。我的应用程序应该保存图像的 url。 集合视图中的每个单元格都从保存的 url 中得到一个 url。设置 url 后,单元格从 url 检索图像并将图像放入自身。

问题是取错了url。取的url可以转换成数据,但是那个数据不能转换成UIImage。从拖放中保存的 url 不是图像的 url,它似乎是 google 搜索或其他东西的 url。

我需要能够为图像保存正确的 url,以便 ImageCell 可以从 url.


当我在网络浏览器中输入 url 时,我收到了这样的页面。

ImageViewController

import UIKit

class ImageViewController: UIViewController{

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    var gallery = [URL]()

}

extension ImageViewController: UICollectionViewDelegate, UICollectionViewDataSource{

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return gallery.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell
        cell.url = gallery[indexPath.item]
        return cell
    }
}

extension ImageViewController: UICollectionViewDropDelegate{

    func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool {
        return session.canLoadObjects(ofClass: NSURL.self) && session.canLoadObjects(ofClass: UIImage.self)
    }

    func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
        return UICollectionViewDropProposal(operation: .copy)
    }

    func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) {

        // Get the destion index path, if there's none set, just insert at the beginning
        let destinationIndexPath = coordinator.destinationIndexPath ?? IndexPath(item: 0, section: 0)

        // Process all items being dragged
        for item in coordinator.items {

                // External drops must provide url and an image that we'll use to get an aspect-ratio
                var url: URL?

                // Get the URL
                item.dragItem.itemProvider.loadObject(ofClass: NSURL.self) { [weak self] (provider, error) in

                    url = provider as? URL  //Check that url is valid

                    // If both url and ratio were provided, perform the actual drop
                    if url != nil{
                        DispatchQueue.main.async {
                            collectionView.performBatchUpdates({
                                // Update model
                                self?.gallery.insert(url!, at: destinationIndexPath.item)

                                // Update view
                                collectionView.insertItems(at: [destinationIndexPath])

                                // Animates the item to the specified index path in the collection view.
                                coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)
                            })
                        }
                    }
                }
            }

    }

}

ImageCell

class ImageCell: UICollectionViewCell{
    var url: URL?{
        didSet{
            self.fetchImage(withURL: url!)
        }
    }
    @IBOutlet var imageView: UIImageView!

    private func fetchImage(withURL url: URL) {
        DispatchQueue.global(qos: .userInitiated).async { [weak self] in
            guard let data = try? Data(contentsOf: url) else {
                return
            }

            guard let image = UIImage(data: data) else {
                print("Couldn't convert data to UIImage")
                print("The url is")
                print(url)
                return
            }

            // If by the time the async. fetch finishes, the imageURL is still the same, update the UI (in the main queue)
            if self?.url == url {
                DispatchQueue.main.async {
                    self?.imageView.image = image
                }
            }
        }
    }

}

GITHUB

Here is my project on github

要从 google 图像拖放提供的 URL 中提取图像 url,您可以将这些扩展添加到 URL。然后在 url 保存到 (url) 的变量上,您可以使用 url!.imageURL 而不仅仅是 url![=14= 访问图像 url ]

extension URL {
    var imageURL: URL {
        if let url = UIImage.urlToStoreLocallyAsJPEG(named: self.path) {
            // this was created using UIImage.storeLocallyAsJPEG
            return url
        } else {
            // check to see if there is an embedded imgurl reference
            for query in query?.components(separatedBy: "&") ?? [] {
                let queryComponents = query.components(separatedBy: "=")
                if queryComponents.count == 2 {
                    if queryComponents[0] == "imgurl", let url = URL(string: queryComponents[1].removingPercentEncoding ?? "") {
                        return url
                    }
                }
            }
            return self.baseURL ?? self
        }
    }
}

extension UIImage
{
    private static let localImagesDirectory = "UIImage.storeLocallyAsJPEG"

    static func urlToStoreLocallyAsJPEG(named: String) -> URL? {
        var name = named
        let pathComponents = named.components(separatedBy: "/")
        if pathComponents.count > 1 {
            if pathComponents[pathComponents.count-2] == localImagesDirectory {
                name = pathComponents.last!
            } else {
                return nil
            }
        }
        if var url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first {
            url = url.appendingPathComponent(localImagesDirectory)
            do {
                try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true)
                url = url.appendingPathComponent(name)
                if url.pathExtension != "jpg" {
                    url = url.appendingPathExtension("jpg")
                }
                return url
            } catch let error {
                print("UIImage.urlToStoreLocallyAsJPEG \(error)")
            }
        }
        return nil
    }

    func storeLocallyAsJPEG(named name: String) -> URL? {
        if let imageData = self.jpegData(compressionQuality: 1.0) {
            if let url = UIImage.urlToStoreLocallyAsJPEG(named: name) {
                do {
                    try imageData.write(to: url)
                    return url
                } catch let error {
                    print("UIImage.storeLocallyAsJPEG \(error)")
                }
            }
        }
        return nil
    }
}