I am working on project with different files (video, photo, links) so we are going to use LPLinkView to present it directly from url like following image
So please if there is anyway to hide the footer view that include metadata (title, text, url) and only keep the preview?
If not can't you suggest me any library that do what we want?
Looking to here from your side
Thanks
You can't manage any internal properties of a LPLinkView, but you can use LPLinkMetadata instead and extract the images from its imageProvider.
So, you can create your own function to get the image from the imageProvider
import LinkPresentation
import UIKit
func getImageFromMetadata(url: URL, completion: #escaping (UIImage)-> Void) {
LPMetadataProvider().startFetchingMetadata(for: url) { (linkMetadata, error) in
guard let linkMetadata = linkMetadata, let imageProvider = linkMetadata.imageProvider else { return }
imageProvider.loadObject(ofClass: UIImage.self) { (image, error) in
guard error == nil else {
print("provider error")
return
}
if let image = image as? UIImage {
// now you can do whatever you want with the image.
// for we now are going to send it to the completion handler
DispatchQueue.main.async {
completion(image)
}
} else {
print("image not found")
}
}
}
}
Now you can use the function to load the image to your UIImageView
guard let url = URL(string: "https://www.youtube.com/watch?v=-YyeaaDOWho") else { return }
getImageFromMetadata(url: url) { image in
imageView.image = image
}
Related
I have a function to import images from an array of NSItemProvider (passed from a PHPickerViewController) and I need to maintain transparency in the images. Any images in PNG format are correctly maintaining transparency but WebP images are not. The image import code is as follows:
private func save(itemProviders: [NSItemProvider]) async throws -> Int {
return try await withCheckedThrowingContinuation({ continuation in
let group = DispatchGroup()
var failureCount = 0
for item in itemProviders {
// webp format image
if item.hasItemConformingToTypeIdentifier(UTType.webP.identifier) {
group.enter()
item.loadDataRepresentation(forTypeIdentifier: UTType.webP.identifier) { data, error in
defer {
group.leave()
}
guard let data, let image = UIImage(data: data) else {
return
}
self.saveImage(image)
}
}
else if item.canLoadObject(ofClass: UIImage.self) {
// other image formats, including PNG
group.enter()
item.loadObject(ofClass: UIImage.self) { (image, error) in
defer {
group.leave()
}
guard let image = image as? UIImage else {
return
}
self.saveImage(image)
}
}
else {
failureCount += 1
}
}
group.notify(queue: .main) {
continuation.resume(returning: failureCount)
}
})
}
Please note that the saveImage function is a simple resize and save to disk function, and I have been able to verify that transparency is not being lost during that step.
It seems as though transparency is being lost during the call to item.loadDataRepresentation(forTypeIdentifier: UTType.webP.identifier) or when the resulting Data is used to instantiate a UIImage. The code in the WebP handling block seems to be irreducibly simple though so I'm not sure how I can possibly fix this issue.
I'm using a code I got off here to download some images and present them in a collection view.
Heres the code:
func downloadImage (url: URL, completion: () -> Void){
let session = URLSession(configuration: .default)
let downloadPicTask = session.dataTask(with: url) { (data, response, error) in
if let e = error {
print("Error downloading image \(e)")
} else {
if let res = response as? HTTPURLResponse {
print("Downloaded image with response code \(res.statusCode)")
if let imageData = data {
let image = UIImage(data: imageData)
self.globalImages.append(image!)
print("what does this say?-->", self.globalImages.count)
} else {
print("Couldn't get image: Image is nil")
}
} else {
print("Couldn't get response code for some reason")
}
}
}
completion()
downloadPicTask.resume()
}
And I'm calling the download image in view did load where URL is the URL. (this URL works and I can download image).
downloadImage(url: url) { () -> () in
collectionView.ReloadData()
}
The completion handler I've tried calls reloadData() way too soon. I'm wanting it to be called when the image is finished downloading? so then the image can be displayed as soon as it's downloaded.
What is wrong with this code?
Please help!
You would call the completion handler as soon as you have the image. So, in your code:
if let imageData = data {
let image = UIImage(data: imageData)
self.globalImages.append(image!)
print("what does this say?-->", self.globalImages.count)
// call the completion handler here
Be aware, though, that you are likely to have other issues caused by data sharing across multiple threads, and also that your idea of storing the downloaded images successively in an array (globalImages) is not likely to work correctly.
I have an array filled with parsed json data including image url's. But when i try to see that images inside uiimageview, it doesn't the show. What should i do
I printed the url. This is my url inside array.
This is my array
var feedResult = [Result]()
It shows the name inside collectionview but i couldn't see the images. I used named like everybody does. But what is missing?
let info = feedResult[indexPath.row]
cell.appLabel.text = info.artistName
cell.customCollectionImage.image = UIImage(named: info.artWorkUrl)
You have to download the image Data using the url you got, only then you will use the downloaded data, like so:
imageView.image = UIImage(data: downloadedData)
Here is a quick subclass of UIImageView that does the downloading:
class URLImageView: UIImageView {
func download(url urlString: String) {
guard let url = URL(string: urlString) else { return }
let task = URLSession.shared.dataTask(with: url) { (downloadedData, _, error) in
guard error == nil && downloadedData != nil else { return }
DispatchQueue.main.async{
self.image = UIImage(data: downloadedData!)
}
}
task.resume()
}
}
Update-1 Use the download function using UIImageView extension, without subclassing, like so:
extension UIImageView {
func download(url urlString: String) {
guard let url = URL(string: urlString) else { return }
let task = URLSession.shared.dataTask(with: url) { (downloadedData, _, error) in
guard error == nil && downloadedData != nil else { return }
DispatchQueue.main.async{
self.image = UIImage(data: downloadedData!)
}
}
task.resume()
}
}
Usage:
cell.customCollectionImage.download(url: info.artWorkUrl)
By using UIImage(named: info.artWorkUrl) you are not accessing the image in your array but the images in your Assets.xcassets (assets that you add manually in your project).
You need to download the image from the artWorkUrl and then directly use the downloaded image like this:
cell.customCollectionImage.image = UIImage(data: yourImageData)
Where yourImageData is what you have downloaded from the server with the artWorkUrl.
In my project, I show a UITableView, which currently has text describing a show's name and genre loading from a remote JSON file.
That all works. What I want next is to use the URL from the JSON file and load a thumbnail next to each show.
Using a tutorial, I have added a function to download the remote image with a print to test if it's successful.
if let shows_list = json as? NSArray
{
for i in 0 ..< data_list.count
{
if let shows_obj = shows_list[i] as? NSDictionary
{
let show_name = shows_obj["show"] as? String
let show_genre = shows_obj["genre"] as? String
let show_image = shows_obj["thumbnail"] as? String
TableData.append(show_name! + " | " + show_genre!)
let testPictureURL = URL(string: show_image!)!
let session = URLSession(configuration: .default)
// Here's the download task where I'm grabbing the image
let downloadPicTask = session.dataTask(with: testPictureURL) { (data, response, error) in
// The download has finished.
if let e = error {
print("Error downloading cat picture: \(e)")
} else {
// No errors found.
if let res = response as? HTTPURLResponse {
print("Downloaded picture with response code \(res.statusCode)")
if let imageData = data {
// Now I know I have data, so I think I can use UIImage to convert it into an image
let image = UIImage(data: imageData)
} else {
print("Couldn't get image: Image is nil")
}
} else {
print("Couldn't get response code for some reason")
}
}
}
downloadPicTask.resume()
}
There are three items in the JSON array, and I get three printed statements that the picture was download: but the image does not appear.
My theory: since this is a table, maybe I have to add this as an accessory, but there isn't an image accessory subclass.
I am new to Swift -- do you have any ideas about how I should append this uploaded image to the table.
This is probably being caused by the asynchronous behavior of URLSession so when the requested image returns the view is already loaded.
To solve that, you can use a callback, for instance:
func myFunction(completion: (returnedImage -> UIIMage) -> Void){
//...
let downloadPicTask = session.dataTask(with: testPictureURL) { (data, response, error) in
//...
let image = UIImage(data: imageData)
completion(returnedImage: image)
//...
}
downloadPicTask.resume()
}
}
By using a callback, let's say that you have a method called myFunction(completion:), so now when you call the method you can handle whatever comes back from completion:
myFunction { (image) in
DispatchQueue.main.async { cell.imageView.image = image }
}
This question already has answers here:
How can I get the Data from NSURLSession.sharedSession().dataTaskWithRequest
(2 answers)
Closed 5 years ago.
I have a URL and want to download the image via a return function, however I cant get it to cooperate properly, here is my func:
func getTabImage(url: URL) -> UIImage {
Alamofire.request(url)
.responseImage { response in
if let image = response.result.value {
return image
} else {
print("Failed to get image")
}
}
}
I pass in the URL, and want a UIImage returned from the alamofire response.
But i get
Unexpected non-void return value in void function
for the return statement.
How can i achieve this correctly?
You can use the below function for downloading the image:
func getImage(_ url:String,handler: #escaping (UIImage?)->Void) {
print(url)
Alamofire.request(url, method: .get).responseImage { response in
if let data = response.result.value {
handler(data)
} else {
handler(nil)
}
}
}
Uses
getImage("http://") { (image) in
if image != nil {
print(image)
}
}
Or
If you want to set the image on UIImageView use extension of AlamofireImage.
if let imageURL = URL(string: "http://"), let placeholder = UIImage(named: "default") {
imageView.af_setImage(withURL: imageURL, placeholderImage: placeholder) //set image automatically when download compelete.
}