ok guys can I get a little help with my code. When running the app I get an error is there any way to fix this problem?
let fileUrl = dict["fileUrl"]as! String
let url = NSURL(string: fileUrl)
let data = NSData(contentsOf: url! as URL!)
let picture = UIImage(data: data! as Data!)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
Image here
Here I see 4 big fat problems with your code.
You are force casting the value of fileUrl of the dictionary dict to String. If your dictionary doesn't have the value for fileUrl, or if it's not castable to string, your code will crash. You should change that to optional cast like:
if let fileUrl = dict["fileUrl"] as? String
{
//your code if you have fileUrl
}
When creating the url to the file, you are using the wrong initialization method, you should be using this:
let url = URL(fileURLWithPath: fileUrl)
After you have the url to the file, you should also check if you have the data of the file, because contentsOfFile: initializer of the NSData returns the optional object, which may be nil, so another if check:
if let data = NSData(contentsOf: url) {\\ code with the data}
init?(data: Data) initializer of the UIImage also returns optional object, so if the required by latter code, you should also check if you have the image or nil with if statement.
The result code should be something like:
if let fileUrl = dict["fileUrl"] as? String {
let url = URL(fileURLWithPath: fileUrl)
if let data = NSData(contentsOf: url) {
let image = UIImage(data: data as Data) // you can cast NSData to Data without force or optional casting
let photo = JSQPhotoMediaItem(image: image)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
}
}
Hope this helps.
Replace the first line of code with this line for optional binding check :-
guard let fileUrl = dict["fileUrl"] as! String else {return}
Yo should do validation in cases where the variable may be nil, the following is an example:
if let fileUrl = dict["fileUrl"] as? String {
let url = URL(string: fileUrl)
do {
let data = try Data(contentsOf: url!)
let picture = UIImage(data: data)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
} catch {
}
}
Related
I'm trying to retrieve the URL from a UserDefault I saved previously, but parsing it to URL fails as states: "Cannot convert NSINLINEDATA to NSURL"
I've tried parsing it to String and then to URL but it only gives nil
Set value
let videourl = info["UIImagePickerControllerReferenceURL"] as? URL
if let videoURL = videourl{
defaults.set(videourl,forKey: "LullabyURL")
}
Get value
let videoURL = defaults.value(forKey: "LullabyURL")
let newStr = String(data: videoURL as! Data, encoding: .utf8)
let vu = URL.init(string:newStr ?? "nil")
let player = AVPlayer(url: vu!)
You can use built in method func url(forKey defaultName: String) -> URL? to retrieve URL as below,
if let defaultsUrl = UserDefaults.standard.url(forKey: "urlString") {
let player = AVPlayer(url: defaultsUrl)
}
let url = URL(string: "http://i.imgur.com/w5rkSIj.jpg")
let data = try? Data(contentsOf: url)
if let imageData = data {
let image = UIImage(data: imageData)
}
I am trying to do the above for loading an image from url but when i type the Data(contentsOf: url) line i get an error saying "Argument passed to call that takes no argumens". What may be causing this? NSData(contentsOf: url) works but i need the Data one
url is optional variable so use optional binding
guard let url = URL(string: "http://i.imgur.com/w5rkSIj.jpg") else {
return
}
let data = try? Data(contentsOf: url)
if let imageData = data {
let image = UIImage(data: imageData)
}
I am having and imageView and I am getting the userData from the server when loggedIn in the userData I have a parameter for "profilePic":"penguins.jpg". now I am adding the domain like "http://.....(self.userData.value(forKey: "profilePic")!)" and saving this value into a string variable to store and when I am accessing the value and trying to convert the url into data and adding to imageView.image it is throwing : unexpectedly found nil while unwrapping an optional value..
All my other userData like name,address,phoneNumber are showing fine except for Image.
My Code:
here are the some of the many ways I tried:
way:1
let ad : AppDelegate = UIApplication.shared.delegate as! AppDelegate
let imageUrlString = ad.userImagePath
let imageUrl:URL = URL(string: imageUrlString)! // it is throwing error here(: unexpectedly found nil while unwrapping an optional value)
DispatchQueue.global(qos: .userInitiated).async {
let imageData:NSData = NSData(contentsOf: imageUrl)!
DispatchQueue.main.async {
let image = UIImage(data: imageData as Data)
self.profileImage.image = image
}
}
way:2
if let url = NSURL(string: ad.userImagePath) {
if let data = NSData(contentsOf: url as URL){
if let imageUrl = UIImage(data: data as Data) {
profileImage.image = imageUrl
}
}
}
I have tried different ways to solve this, can't figure out what is my mistake.. finally I am here.. Please someone help he...
I am trying to upload a video to a server file through Alamofire but I couldn't get the "data" going to be passed..its always nil
var videoURL = NSURL(string: "")
//returns Optional(file:///private/var/mobile/Containers/Data/Application/1FB40086-228B-4011-A9D4-7874E2EEF9F4/tmp/4A6AAD76-B899-4B67-8E96-925DA4AE9E93.mov)
let videodata = NSData(contentsOfFile: (videoURL?.absoluteString)!)
//nil
let url = NSURL(fileURLWithPath: (videoURL?.absoluteString)!)
let videodata = NSData(contentsOf: url as URL)
//nil
If I get data would lead a way for me to do this:
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append (videodata as! Data, withName: "file", fileName: "file.mov", mimeType: "video/quicktime")
enter code here
EDIT::
thank you guys, with your help I have struggled my way out of there to this file not found error, but I can see the file is being saved in my gallery, any clue would save my day.
print (videoURL!)
//returns file:///private/var/mobile/Containers/Data/Application/3F280477-DA16-4A67-AE60-D6247143352E/tmp/1E4AC002-6AD0-41E1-9E0D-A09B697F81F7.mov
print (videoURL!.path!)
// returns /private/var/mobile/Containers/Data/Application/3F280477-DA16-4A67-AE60-D6247143352E/tmp/1E4AC002-6AD0-41E1-9E0D-A09B697F81F7.mov
var videoData = NSData()
let path = videoURL!.path!
if FileManager.default.fileExists(atPath: path) {
}else {
print("Could not fin file at url: \(videoURL!.path!)")
// here it throws file not found
}
In Swift 3 use native URL and Data instead of NSURL and NSData.
if let videoURL = URL(string: urlString), let videodata = try? Data(contentsOf: videoURL) {
//Add code of Alamofire here
}
Using absoluteString returns a string that includes file:// at the beginning and you don't want that. You need to return the path of the URL
guard let videoPathString = videoURL.path as? String else {
//handle error here if you can't create a path string
return
}
var videoData = NSData()
//check if file exists at this path first
if (NSFileManager.defaultManager().fileExistsAtPath(videoPathString)) {
videoData = NSData(contentsOfFile: NSString(videoPathString))
} else {
//if file does not exist at that path, handle here
}
Using this code, I extract an image from a Share Extension and I write it to a directory I created in an App Group.
let content = self.extensionContext!.inputItems[0] as! NSExtensionItem
let contentType = kUTTypeImage as String
for attachment in content.attachments as! [NSItemProvider] {
if attachment.hasItemConformingToTypeIdentifier(contentType) {
attachment.loadItem(forTypeIdentifier: contentType, options: nil) { data, error in
// from here
if error == nil {
let url = data as! NSURL
let originalFileName = url.lastPathComponent
if let imageData = NSData(contentsOf: url as URL) {
let img = UIImage(data:imageData as Data)
if let data = UIImagePNGRepresentation(img!) {
// write, etc.
}
}
}
}
Anything is working fine.
What I'd like to know is if it is possible to reduce some code: in particular, after if error == nil, I:
cast data to NSURL;
use NSURL to get a NSData;
use NSData to get a UIImage;
use UIImage to get a UIImagePNGRepresentation;
Aside from avoiding the creation of the imageData variable, isn't there a way to (safely) achieve the same goal with fewer steps?
First of all you need to use native Data and URL instead of NSData & NSURL also if you want to write file in DocumentDirectory then you can directly use that imageData no need to make UIImage object from it and then convert it to data using UIImagePNGRepresentation.
if let url = data as? URL, error == nil {
let originalFileName = url.lastPathComponent
if let imageData = try? Data(contentsOf: data) {
// write, etc.
var destinationURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
destinationURL.appendPathComponent("fileName.png")
try? imageData.write(to: destinationURL)
}
}