Search code examples
iosswiftcompletionhandlershare-extension

Function that return current URL with completion Handler


I have a ShareExtension in which I like need to get the current URL. This is my function for it:

var html: String?

    if let item = extensionContext?.inputItems.first as? NSExtensionItem,
        let itemProvider = item.attachments?.first,
        itemProvider.hasItemConformingToTypeIdentifier("public.url") {
        itemProvider.loadItem(forTypeIdentifier: "public.url", options: nil) { (url, error) in
            if (url as? URL) != nil {
                html = (self.getHTMLfromURL(url: url as? URL))
            }

        }
    }

My problem is that I need the html but when using that variable right after that function html is still empty. I think I need some sort of completion handler but I tried different things now and can not get it right...

This is how my whole function looks like at the moment (not working, as html becomes an empty String)

@objc func actionButtonTapped(){

    do {

        var html: String?

        if let item = extensionContext?.inputItems.first as? NSExtensionItem,
            let itemProvider = item.attachments?.first,
            itemProvider.hasItemConformingToTypeIdentifier("public.url") {
            itemProvider.loadItem(forTypeIdentifier: "public.url", options: nil) { (url, error) in
                if (url as? URL) != nil {
                    html = (self.getHTMLfromURL(url: url as? URL))
                }

            }
        }


        let doc: Document = try SwiftSoup.parse(html ?? "")

        let priceClasses: Elements = try doc.select("[class~=(?i)price]")

        for priceClass: Element in priceClasses.array() {
            let priceText : String = try priceClass.text()
            print(try priceClass.className())
            print("pricetext: \(priceText)")
        }

        let srcs: Elements = try doc.select("img[src]")
        let srcsStringArray: [String?] = srcs.array().map { try? $0.attr("src").description }

        for imageName in srcsStringArray {
            print(imageName!)
        }

    } catch Exception.Error( _, let message) {
        print(message)
    } catch {
        print("error")
    }

}

The Goal is to have a extra function to get the url (1st code example) with a completion handler in which I can work with the created html.


Solution

  • the problem was that I didn't realize that I already had a completionHandler with loadItems. So what I did now was to put the whole do & catch block in another method and called it in the completion handler like this:

    @objc func actionButtonTapped(){
    
            var html: String?
    
            if let item = extensionContext?.inputItems.first as? NSExtensionItem,
                let itemProvider = item.attachments?.first,
                itemProvider.hasItemConformingToTypeIdentifier("public.url") {
                itemProvider.loadItem(forTypeIdentifier: "public.url", options: nil) { (url, error) in
                    if (url as? URL) != nil {
                        html = (self.getHTMLfromURL(url: url as? URL))
                        print("bruh")
    
                        self.doStuff(html: html)
                    }
                }
            }
    }
    
    func doStuff(html: String?){
        do {
            let doc: Document = try SwiftSoup.parse(html ?? "")
    
            let priceClasses: Elements? = try doc.select("[class~=(?i)price]")
    
                for priceClass: Element in priceClasses!.array() {
                let priceText : String = try priceClass.text()
                print(try priceClass.className())
                print("pricetext: \(priceText)")
            }
    
            let srcs: Elements = try doc.select("img[src]")
            let srcsStringArray: [String?] = srcs.array().map { try? $0.attr("src").description }
    
            for imageName in srcsStringArray {
                print(imageName!)
            }
    
                } catch Exception.Error( _, let message) {
                    print(message)
                } catch {
                    print("error")
    
            }
    }