I have a Base64 string saved from Swift into mysql db. When it comes back, it does not display an image.
How it looks in the db:
LzlqLzRBQVFTa1pKUmdBQkFRQUFTQUJJQUFELzRRQk1SWGhwWmdBQVRVMEFLZ0FBQUFnQUFnRVNBQU1BQUFBQg0KQUFFQUFJZHBBQVFBQUFBQkFBQUFKZ0FBQUFBQUFxQUNBQEZMUlUlJSUUFVVVVVQUZGRkZBQlJSUlFBVVVVVUFGRkZGQUJSUlJRQVVVVVVBRkZGRkFCUlJSUUFVVQ0KVVVBRkZGaWdBcEtXaWdBcEtXaw0Kb0FLS0tLQUNpaWlnQW9vb29BS0tLS0FDaWlpZ0Fvb29vQVNpbG9vQVNpbG9vQVNpaWlnQW9vb29BS0tLS0FDaQ0KaWlnQW9vb29BS0tLS0FDaWlpZ0Fvb29vQUtLS0tB
and this is how I am attempting to receive it but its not working:
let partUrl = "data:image/jpg;base64,";
let appndd = partUrl.stringByAppendingString(baseStringNew!)
let urlWeb = appndd
let requestURL: NSURL = NSURL(string: urlWeb)!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
if error == nil {
NSLog("Success!")
dispatch_async(dispatch_get_main_queue(), {
imageNewView.layer.cornerRadius = 10.0
imageNewView.clipsToBounds = true
// Adding a border to the image profile
imageNewView.layer.borderWidth = 1.0
imageNewView.layer.borderColor = UIColor.grayColor().CGColor
imageNewView.image = UIImage(data:data!)
})
} else {
NSLog("Fail")
}
} //end of task
task.resume()
This displays a blank image in the UIImageView. How do I get this string to show up as an image?
Make sure that you prepend your data with data:image/png;base64.
Here is an q&a about this, How to display a base64 image within a UIImageView?
You might want to check the base64 string you stored and retrieved from your MySQL DB. Try using BLOB data type.
Then converting base64 string to NSData then UIImage is pretty easy and straightforward.
let rawData = NSData.init(contentsOfURL: NSURL(string: "http://cdn.sstatic.net/stackoverflow/company/img/logos/so/so-logo.png")!)!
let base64String = rawData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
let imageData = NSData(base64EncodedString: base64String, options: .IgnoreUnknownCharacters)
let image = UIImage(data: imageData!)
Related
My iOS app (Swift 3) needs to important images from other apps using an Action Extension. I'm using the standard Action Extension template code which works just fine for apps like iOS Mail and Photos where the image shared is a URL to a local file. But for certain apps where the image being shared is the actual image data itself, my action extension code isn't getting the image.
for item: Any in self.extensionContext!.inputItems {
let inputItem = item as! NSExtensionItem
for provider: Any in inputItem.attachments! {
let itemProvider = provider as! NSItemProvider
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { //we'll take any image type: gif, png, jpg, etc
// This is an image. We'll load it, then place it in our image view.
weak var weakImageView = self.imageView
itemProvider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil, completionHandler: { (imageURL,
error) in
OperationQueue.main.addOperation {
if let strongImageView = weakImageView {
if let imageURL = imageURL as? NSURL {
strongImageView.image = UIImage(data: NSData(contentsOf: imageURL as URL)! as Data)
let imageData = NSData(contentsOf: imageURL as URL)! as Data
self.gifImageView.image = UIImage.gif(data: imageData)
let width = strongImageView.image?.size.width
let height = strongImageView.image?.size.height
.... my custom logic
}
}
For reference, I reached out to the developer for one of the apps where things aren't working and he shared this code on how he is sharing the image to the Action Extension.
//Here is the relevant code. At this point the scaledImage variable holds a UIImage.
var activityItems = Array<Any?>()
if let pngData = UIImagePNGRepresentation(scaledImage) {
activityItems.append(pngData)
} else {
activityItems.append(scaledImage)
}
//Then a little later it presents the share sheet:
let activityVC = UIActivityViewController(activityItems: activityItems,applicationActivities: [])
self.present(activityVC, animated: true, completion: nil)
Figured it out thanks to this post which explains the challenge quite well https://pspdfkit.com/blog/2017/action-extension/ . In summary, we don't know if the sharing app is giving us a URL to an existing image or just raw image data so we need to modify the out of the box action extension template code to handle both cases.
for item: Any in self.extensionContext!.inputItems {
let inputItem = item as! NSExtensionItem
for provider: Any in inputItem.attachments! {
let itemProvider = provider as! NSItemProvider
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { //we'll take any image type: gif, png, jpg, etc
// This is an image. We'll load it, then place it in our image view.
weak var weakImageView = self.imageView
itemProvider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil, completionHandler: { (imageURL,
error) in
OperationQueue.main.addOperation {
if let strongImageView = weakImageView {
if let imageURL = imageURL as? NSURL {
strongImageView.image = UIImage(data: NSData(contentsOf: imageURL as URL)! as Data)
let imageData = NSData(contentsOf: imageURL as URL)! as Data
self.gifImageView.image = UIImage.gif(data: imageData)
let width = strongImageView.image?.size.width
let height = strongImageView.image?.size.height
.... my custom logic
}
else
guard let imageData = imageURL as? Data else { return } //can we cast to image data?
strongImageView_.image = UIImage(data: imageData_)
//custom logic
}
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)
}
}
I'm trying to convert NSURL to NSData. My url string is a local file url which I'm getting from my device.
let url = NSURL(string: url)
let imageData = NSData(contentsOfURL: url)
let image = UIImage(data: imageData)
I'm getting NSURL value properly. But while converting it to NSData it gives nil value. I know there are similar questions in stackoverflow but none of them solves my problem. I'm using swift 2.2
If the string points to a local file url then you are using the wrong API. The correct one is
let url = NSURL(fileURLWithPath: urlString)
NSURL(string: is only for URL strings which start with a valid file scheme (e.g. http or ftp)
Try this code.
let urlString = "/var/mobile/Media/DCIM/101APPLE/IMG_1827.JPG"
let url = URL(fileURLWithPath: urlString)
let imageData = NSData(contentsOf: url)
let image = UIImage(data: imageData as! Data)
The Correct one is use contentsOf: forecastURL! as URL instead of contentsOf: forecastURL
let forecastURL = NSURL(string: "http://photos.state.gov/libraries/media/788/images/90x90.gif")
let testImage = NSData (contentsOf: forecastURL! as URL)
print("data",testImage!)
let image = UIImage(data: testImage! as Data)
print("imaGE :-",image!)
I'm trying to get user image from twitter(parse- twitter login) using this code :
if PFTwitterUtils.isLinkedWithUser(PFUser.currentUser()!) {
let screenName = PFTwitterUtils.twitter()?.screenName!
let requestString = NSURL(string: "https://api.twitter.com/1.1/users/show.json?screen_name=" + screenName!)
let request = NSMutableURLRequest(URL: requestString!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
PFTwitterUtils.twitter()?.signRequest(request)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
print(data)
print(response)
print(error)
if error == nil {
var result: AnyObject?
do {
result = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments)
} catch let error2 as NSError? {
print("error 2 \(error2)")
}
let names: String! = result?.objectForKey("name") as! String
let separatedNames: [String] = names.componentsSeparatedByString(" ")
//self.firstName = separatedNames.first!
//self.lastName = separatedNames.last!
let urlString = result?.objectForKey("profile_image_url_https") as! String
let hiResUrlString = urlString.stringByReplacingOccurrencesOfString("_normal", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
let twitterPhotoUrl = NSURL(string: hiResUrlString)
let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
let twitterImage: UIImage! = UIImage(data:imageData!)
self.userImg = UIImageView(image: twitterImage)
}
}).resume()
}
but it imageData is nil
let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
let twitterImage: UIImage! = UIImage(data:imageData!)
twitterphotoUrl actually have the link
any help???
I would guess that you're getting an ATS exception from the pbs.twimg.com URL, so you're not getting the data, so you fall over when you force unwrap it. You should add that domain to the list of ATS exceptions as shown here, [documented here] (https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html) (search for NSExceptionDomain on that page) and discussed in many other places.
In addition to that, force unwrapping the results of URL calls is always a bad idea, since any number of things could prevent a data object being created. You should be using guard or if let statements in this case.
Try with below code,
if let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.userImg.image = UIImage(image: imageData!)
})
}
Hope this will work
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
at the above line,i'm getting fatal error
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
Code :
let ImageName = obj["image"] as! String
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
Imgtask.resume()
From the above code im trying to store my image from database in annotation
if i printed the 'ImageName' it returns the name from the database correctly, but unable to retain the image
it resulting in the error while running.
You say that
if i printed the 'ImageName' it returns the name from the database correctly
Then that must mean that the ImageName is not valid for a URL
If you look at the description of NSURL(string:) it says:
The URL string with which to initialize the NSURL object. This URL string must conform to URL format as described in RFC 2396, and must not be nil. This method parses URLString according to RFCs 1738 and 1808.
So the question is...how does ImageName look? And can you create a URL from it?
Apart from that, it is always a good idea to use ? instead of ! as #PhillipMills says
Update: I can see that you have posted an example of your URL now. If I do this in a playground:
let url = NSURL(string: " goo.gl/pBmA0d")
I get nil in return, so it would seem that short URLs and NSURLaren't the best of friends.
Update 2: hmm, guess I spoke to quickly, if you look at the above you can see that I have a space before the goo.gl part, if I change that to:
let url = NSURL(string: "goo.gl/pBmA0d")
it actually works, I get a NSURL object.
But another thing I stumbled upon in your code. You declare ImageName as a String here:
let ImageName = obj["image"] as! String
So you don't have to wrap it in \() later on
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
You could simply say:
let imageURL = NSURL(string: ImageName)
And then...as others has said, it is always a good idea to use ? instead of !
So you could write:
if let imageName = obj["image"] as? String,
let imageURL = NSURL(string: imageName) {
//we're in business :-)
}
and be safe and sound
Try to use guard or if let for helping yourself.
let ImageName = obj["image"] as! String
if let imgURL = NSURL(string: ImageName) {
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){ (data, response, error) -> Void in
if (error == nil && data != nil)
{
// What's that func??
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
}
Imgtask.resume()
Don't make force unwrap...use if let to avoid crash ...
if let img = obj["image"] as? String,
imgURL = NSURL(string: img) {
// ... continue with your code ...
}
Please try the following code:
//ImageName is a String type.
guard let ImageName = obj["image"] as? String , let imgURL = NSURL(string: ImageName) else{
return
}
let request: NSURLRequest = NSURLRequest(URL:imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
Imgtask.resume()