How I can dowload GIF image in swift - ios

I am developing some tumblr client. And i want to download all photos in dashboard and save them to documentDirectory. Some of them is jpg some are gif. I have successfully download jpg images with this code:
do {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsURL.appendingPathComponent(fname)
if let pngImageData = UIImagePNGRepresentation(myImage!) {
try pngImageData.write(to: fileURL, options: .atomic)
print(fname + " - saved")
}
} catch {print(fname + " - not saved") }
myImage is the image which is downloaded from URL. This code is work for jpg images but not good for gifs.
And lastly i read these files with this:
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let filePath = documentsURL.appendingPathComponent(fname).path
if FileManager.default.fileExists(atPath: filePath) {
return UIImage(contentsOfFile: filePath)!
}
It's work for jpg but not for gifs. when i try this writing/reading codes on gifs images, i got just image not animation.
Can you show me the way pls with an example will be awesome.
Thank you.

I personally used this tinnie tool for GIFs. Simply add the iOSDevCenters+GIF.swift file directly to your project and use it as shown below
1. Online URL
let imageURL = UIImage.gifImageWithURL(gifURL)
let yourImageView = UIImageView(image: imageURL)
2. Local Filename
let imageName = UIImage.gifImageWithName(imageName)
let yourImageView = UIImageView(image: imageName)
3. Using Data
let imageData = NSData(contentsOf: Bundle.main.url(forResource: "name", withExtension: ".gif"))
let imageData = UIImage.gifImageWithData(imageData)
let yourImageView = UIImageView(image: imageData)

Actually your first code is not working correctly either.
What you are receiving is the image. You do not need or want to translate it into some other kind of image (UIImagePNGRepresentation). Just save the data. Later, read the data directly into a UIImage.

I think there is no problem with downloading and you are just trying to present it as a png; instead try to present this saved data with this library, for example

Try this:
#import AssetsLibrary
let lib = ALAssetsLibrary()
let data = NSData(contentsOfURL: getCurrentGIFURL)
lib.writeImageDataToSavedPhotosAlbum(data, metadata: nil) { (url, err) in
}

Related

iOS Write Data to file, FILE DOES NOT EXIST

I'm tryin to write the datas of an Image in the cacheDirectory, like this :
let imageData = UIImageJPEGRepresentation(image, 1.0) else { fatalError("Impossible to read the image") }
try! imageData.write(to: cachedImageURL, options: .atomic)
print(fileManager.fileExists(atPath: cachedImageURL.absoluteString))
Where image is a working UIImage.
the Print statement always returns False. The file is never written, and any exception is raised due to the "try!"
Any idea ?
printing the cachedImageURL, it looks like this
file:///var/mobile/Containers/Data/Application/7B6B72C8-E794-4474-A658-48B66AEA31EC/Library/Caches/79d0e60e-5961-4538-bd9f-28187f4e26d0.jpg
Just figured out. The problem come from my print
print(fileManager.fileExists(atPath: cachedImageURL.absoluteString))
which should be cachedImageURL.path insteadOf cachedImageURL.absoluteString
print(fileManager.fileExists(atPath: cachedImageURL.path))
You can Try below Code for saving Images to Caches Directory
*NOTE : if you are saving more than one, please give different image name for all
let fileManager = FileManager.default
let imageName = "image.jpg" //Need to change if more images want to save
do {
let cachesDirectory = try fileManager.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
let fileURL = cachesDirectory.appendingPathComponent(imageName)
let image = your image //Give your image here
if let imageData = UIImageJPEGRepresentation(image, 1.0) {
try imageData.write(to: fileURL)
print("Image Saved")
}
} catch {
print(error.localizedDescription)
}

How do I change the value stored in a image file in swift 4

I save my first image and it loads, but when I save the second, the image of the button stays the same as the first image I saved. Can someone show me how to have that files value be able to change?
Here is the code that runs when someone picks an image:
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// choose a name for your image
let fileName = "image.jpg"
// create the destination file url to save your image
let fileURL = documentsDirectory.appendingPathComponent(fileName)
// get your UIImage jpeg data representation and check if the destination file url already exists
if let data = UIImageJPEGRepresentation(pickedImage, 1.0),
!FileManager.default.fileExists(atPath: fileURL.path) {
do {
// writes the image data to disk
try data.write(to: fileURL)
print("file saved")
} catch {
print("error saving file:", error)
}
}
if let image = getSavedImage(named: "image.jpg") { Button1.setImage(image, for: .normal)
}
And here is my code for when the view loads:
if let image = getSavedImage(named: "image.jpg") {
Button1.setImage(image, for: .normal)
}
As #rmaddy mentioned you already saved image thats why image not replaced. but if you want on tap of button image will be change you need to do some extra work, you need to check if image.jpg exist then add new image with diff name.To check image exist use this method, This method return bool value and path of the file if file exist.So on these two values you can remove your existing image or create new image with different name, according to your code behaviour.
static func isFileExit(filename: String) -> (fileExist: Bool? , path: URL?) {
if let dir = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) {
let filepath = URL(fileURLWithPath: dir.absoluteString).appendingPathComponent(filename)
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filepath.path) {
print("FILEAVAILABLE")
return (true, filepath)
}
}
return (false,nil)
}
You're saving your images only if the image doesn't exist, so when you try to save the second image, its not being saved because the first image already exists.
//you should double check what you're doing here
if let data = UIImageJPEGRepresentation(pickedImage, 1.0),
!FileManager.default.fileExists(atPath: fileURL.path) {
do {
// writes the image data to disk
try data.write(to: fileURL)
print("file saved")
} catch {
print("error saving file:", error)
}
}

UIImage from path or filename in Swift 3

i have a bunch of images in my App's Documents Directory. i want to load one of them in an UIImage that i have in my view. this is what i do:
myImage.image = UIImage(named: "image.jpg") // the file exist but this returns nil
I also tried to init the image using:
myImage.image = UIImage(contentsOfFile: imagePath) //this also doesn't work but the path i got starts (at least in the sim) with file://
Anyone can suggest something? I'm kinda a noob in iOS programming.
Thanks
EDIT:
imagePath comes from:
func getImgPath(name: String) -> String
{
let documentsDirectory = self.getDocumentsDirectory()
let fullpath = documentsDirectory.appendingPathComponent(name)
return fullpath.absoluteString
}
This might help
let documentDirectory = FileManager.SearchPathDirectory.documentDirectory
let userDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(documentDirectory, userDomainMask, true)
if let dirPath = paths.first
{
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("name.png")
let image = UIImage(contentsOfFile: imageURL.path)
// Do whatever you want with the image
}
Try adding your images under Assets.xcassets. Then you'll be able to reference your image by:
UIImage(named: 'yourImageName')
You can conveniently add images with various size settings.
You can get the path of the image as fowllows:
let imagePath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("image.jpg")
If this doesn't work, check if your file name is correct.
I understand that if you are downloading images from internet means, you need to convert the URL to UIImage
if let url = URL(string: "your url") {
let data = try? Data(contentsOf: url)
if let imageData = data {
if let image = UIImage(data: imageData) {
imageView.image = image
}
}
}
If i understand your question correct, this will be the answer.

How to save text file as variable in IOS

I am sending some images via socket and I would like to create text file with information about the images to send over the network as well. I right now I can send the images no problem by creating a variable for the image data like so
let imageData = UIImageJPEGRepresentation(someUIImage, 1.0)
How do create a variable with the data of the text file?
let textData = someTextFileAsData.....
Is this what you want?
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
// Get the URL to the file. Below is an example
let fileURL = documentsDirectory.appendingPathComponent("test").appendingPathExtension("txt") // Replace "test" with your fileName and "txt" with your fileExtension
var text = ""
do {
text = try String(contentsOf: fileURL)
} catch {
fatalError("error: \(error.localizedDescription)")
}
Expanding a bit on Anthonin C.'s answer:
Each file in iOS is identified by a URL (just like a webpage, but this is a URL referring to the iOS filesystem). There are a few places in the system where you can save files, most of which you can get the URLs for by reading
FileManager.default.urls(for: SearchPathDirectory, in: SearchPathDomainMask)
(FileManager class reference).
For instance, to save in the user's personal "documents" directory, you would do:
let fileName = "socketLog.txt"
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
//build full path to file
let path = dir.appendingPathComponent(fileName)
do {
try text.write(to: path, atomically: false, encoding: String.Encoding.utf8)
}
catch {/* error handling here */}
}
where text would be the string data you want to save.
You should use write(to:​ URL, atomically:​ Bool) or write(to​File:​ String, atomically:​ Bool) of NSData method to write your data in a file.
In your case it would be :
let imageData = UIImageJPEGRepresentation(someUIImage, 1.0)
imageData.writeToFile("imageData.txt", atomically:true)
You can then restore it like that :
var imageData = NSData(contentsOfFile: "imageData.txt")
And to get back the image from data :
let image : UIImage = UIImage(data: imageData)

UIImageJPEGRepresentation | generateJPEGRepresentation saves image as nil? Swift 3

I am currently designing a database management application with Realm, where I have managed to create and retrieve an object successfully. The problem I am having is with updating/editing - specifically updating the UIImage that the user has uploaded. With Realm, I save the path of the image and then retrieve it by loading that path (in Documents Directory).
When the user tries to save the changed image, for some odd reason the UIImageJPEGRepresentation saves the changed image as nil, thus removing the user's image. It's strange because the initial creation of a data object stores it just fine.
I have tried to check whether the image is being passed correctly with some debugging, and have found that it does so just fine and the right path is being saved on.
Here is my update method:
func updateImage() {
let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let fileURL = documentsDirectoryURL.appendingPathComponent("\(selectedPicPath!)")
if FileManager.default.fileExists(atPath: fileURL.path) {
do {
if profilePic.image != nil {
let image = profilePic.image!.generateJPEGRepresentation()
try! image.write(to: fileURL, options: .atomicWrite)
}
} catch {
print(error)
}
} else {
print("Image Not Added")
}
}
Can anyone see any problems?
let image = profilePic.image!.generateJPEGRepresentation()
Check this line, whether it is returning nil value or data? If nil, then use following code to test your image store, it's working. Also ensure your actual image has JPEG file format extension, that you are trying to generate.
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
// For PNG Image
if let image = UIImage(named: "example.png") {
if let data = UIImagePNGRepresentation() {
let filename = getDocumentsDirectory().appendingPathComponent("copy.png")
try? data.write(to: filename)
}
}
For JPG image
if let image = UIImage(named: "example.jpg") {
if let data = UIImageJPEGRepresentation(image, 1.0) {
let filename = getDocumentsDirectory().appendingPathComponent("copy.jpg")
try? data.write(to: filename)
}
}

Resources