Icons on UIImage disappears - swift

I'm having trouble with the icons I put on default when the app is launched. They don't appear but when I replace it with a photo taken from another controller, it doesn't disappear. Here is part of my code
I tried setting some conditionals but so far doesn't work.
//Default images
let defImage1: UIImage? = UIImage(named: "media")
let defImage2: UIImage? = UIImage(named: "media2")
class PDFViewViewController: UIViewController, UITextFieldDelegate, MFMailComposeViewControllerDelegate {
//Asset image
var image: UIImage? = nil
var secondImage: UIImage? = nil
var codigo = UserDefaults.standard.object(forKey: "code") as? String
//UI Conections
#IBOutlet weak var productPhoto: UIImageView!
#IBOutlet weak var barcodePhoto: UIImageView!
#IBOutlet weak var invNumb: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//declaring default image to image view
productPhoto.image = defImage1
barcodePhoto.image = defImage2
//Assign new image to the view
invNumb.delegate = self
if self.invNumb != nil && self.productPhoto != defImage1 {
if image != UIImage(named: "media") {
saveImage(image: self.image!, withName: "assetPicture")
}
} else {
productPhoto.image = defImage1
}
let theSavedImage = getImage(imageName: "assetPicture")
productPhoto.image = theSavedImage
//Assign values to fields
invNumb.text = codigo
if barcodePhoto != nil {
if productPhoto != nil {
saveImage(image: self.secondImage!, withName: "barcodePicture")
}
} else {
barcodePhoto.image = defImage2
}
let theSecondSavedImage = getImage(imageName: "barcodePicture")
barcodePhoto.image = theSecondSavedImage
}
//Save asset image function
func saveImage(image: UIImage, withName name: String) {
let imageData = NSData(data: UIImageJPEGRepresentation(image, 400)!)
let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let docs = paths[0] as NSString
let name = name
let fullPath = docs.appendingPathComponent(name)
_ = imageData.write(toFile: fullPath, atomically: true)
}
When you tapped the image it will open the camera and save the photo you take inside the image view if you don't have any photo taken, then it stays as the defImage. But when you tapped one image, the other one disappears.

Related

how do i fix this error- Cannot convert value of type 'UIImageView' to expected argument type 'UIImage' in the following code

import UIKit
class UserVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var userImagePicker: UIImageView!
#IBOutlet weak var usernameField: UITextField!
#IBOutlet weak var completeSignInBtn: UIButton!
var userUid: String!
var emailField: String!
var passwordField: String!
var imagePicker: UIImagePickerController!
var imageSelected = false
var username: String!
func uploadImg() {
if usernameField.text == nil {
print("Must have username")
completeSignInBtn.isEnabled = false
}else {
username = usernameField.text
completeSignInBtn.isEnabled = true
}
guard let img = userImagePicker, imageSelected == true else {
print("image must be selected")
return
}
// below is where the error is can you help me?
if let imgData = UIImageJPEGRepresentation(img, 0.2) {
let imgUid = NSUUID().uuidString
let metadata = StorageMetadata()
metadata.contentType = "img/jpeg"
Storage.storage().reference().child(imgUid).put(imgData, metadata: metadata) {
(Metadata, error) in
if error != nil {
print("did not upload image")
}else {
print("uploaded")
//
}
}
}
}
}
I have no Idea on how to fix this error. If there is anyone out there that can help, I would greatly appreciate it.
As I see from the outlet userImagePicker is a UIImageView not UIImage
so to fix the issue I would suggest taking the image from the view by:
changing this line
guard let img = userImagePicker, imageSelected == true else {
to this
guard let img = userImagePicker.image, imageSelected == true else {
assuming that the image is loaded to view after picking it from UIImagePickerController

fatal error: unexpectedly found nil while unwrapping an Optional value when saving NSData to Realm

I want to save an image from an imagePicker with Realm. It works when I choose an picture but not when I don't choose one. I tried to save a standard image when no image is chosen.
But I get the error: fatal error: unexpectedly found nil while unwrapping an Optional value
Location:
class Location: Object{
dynamic var name = ""
dynamic var locationDescription = ""
dynamic var latitude = 0.0
dynamic var longitude = 0.0
dynamic var created = NSDate ()
dynamic var category: Category!
dynamic var imageData: NSData!
}
Add New Entry Controller:
//Image Picker
#IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
var selectedImage = UIImage()
#IBAction func loadImage(_ sender: AnyObject) {
imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(imagePicker, animated: true, completion: nil)
}
//MARK: - Delegates Image Picker
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any])
{
selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
imageView.image = selectedImage
// Dismiss the picker.
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func addNewLocation() {
let realm = try! Realm()
//convert image to NSData
let standardData: NSData = UIImagePNGRepresentation(self.imageView.image!)! as NSData
let selctedImageData = NSData(data: UIImageJPEGRepresentation(selectedImage, 0.9)!)
let emptyData = NSData()
// let data = NSData(data: UIImageJPEGRepresentation(selectedImage, 0.9)!)
var data = NSData()
if selctedImageData == emptyData{
data = standardData
}
else{
data = selctedImageData
}
try! realm.write {
let newLocation = Location()
newLocation.name = self.nameTextField.text!
newLocation.category = self.selectedCategory
newLocation.locationDescription = self.descriptionTextField.text
newLocation.latitude = self.selectedAnnotation.coordinate.latitude
newLocation.longitude = self.selectedAnnotation.coordinate.longitude
newLocation.imageData = data
realm.add(newLocation)
self.locations = newLocation
}
}
Edit:
I replaced the Category Model with an string which is generated from an query.
class Location: Object{
...
dynamic var category = ""
dynamic var imageData: NSData!
}
Your Location model has two properties that are implicitly unwrapped optionals (IUOs): category and imageData. IUOs in Swift are useful when you know that the value might have to store nil, but you can guarantee that it will never be accessed in that state, in ways that the compiler can't imply automatically.
In this case, you're accessing one of these properties before having set its value to something other than nil.
Perhaps self.selectedCategory is nil at the point where it's assigned to the newLocation.category property? It's hard to say given that you didn't include anything related to this value in your sample.
If you can't guarantee that those IUOs will ever be set to something non-nil upon access, I'd suggest that you define them as optionals instead, and handle their nil case specifically.
class Location: Object {
dynamic var name = ""
dynamic var locationDescription = ""
dynamic var latitude = 0.0
dynamic var longitude = 0.0
dynamic var created = NSDate()
dynamic var category: Category?
dynamic var imageData: NSData?
}
I solved the problem like this:
class Location: Object{
dynamic var name = ""
dynamic var locationDescription = ""
dynamic var latitude = 0.0
dynamic var longitude = 0.0
dynamic var category = ""
dynamic var imageData: NSData? = nil
}
//Image Picker
#IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
var selectedImage = UIImage()
#IBAction func loadImage(_ sender: AnyObject) {
imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(imagePicker, animated: true, completion: nil)
}
//MARK: - Delegates Image Picker
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any])
{
selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
imageView.image = selectedImage
// Dismiss the picker.
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func addNewLocation() {
let imageData: NSData = UIImagePNGRepresentation(self.imageView.image!)! as NSData
let realm = try! Realm()
try! realm.write {
let newLocation = Location()
newLocation.name = self.nameTextField.text!
newLocation.category = self.selectedCategory
newLocation.locationDescription = self.descriptionTextField.text
newLocation.latitude = self.selectedAnnotation.coordinate.latitude
newLocation.longitude = self.selectedAnnotation.coordinate.longitude
newLocation.imageData = imageData
realm.add(newLocation)
self.locations = newLocation
}
}

Show Image on UISplitViewController

I'm a newbie in SWIFT and I do some examples application.
The only thing that I can not get worked is to get my Image displayed on Detail Scene (DetailViewController).
On my MasterViewController file I have this to get my multiData file:
...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showData" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = self.multiData[indexPath.section][indexPath.row]
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
// Here I get my multiData
func createData() {
var first: [Dictionary<String,String>] = []
var second: [Dictionary<String,String>] = []
dataSections = ["First Data", "Second Data"]
first.append(["name": "someName", "image": "somePngFile", "someData": "someText"])
second.append(["name": "someName", "image": "somePngFile", "someData": "someText"])
multiData = [first, second]
}
DetailViewController:
...
#IBOutlet weak var label: UILabel!
#IBOutlet weak var text: UITextView!
#IBOutlet weak var image: UIImageView!
...
func configureView() {
if let detail = self.detailItem {
if let labelTitle = label {
labelTitle.text = detail["name"] as! String!
}
if let textData = text {
textData.text = detail["someData"] as! String!
}
// This obvious doesn't work
if let imageFile = image {
imageFile.image = detail["image"] as! UIImage!
}
}
}
So, my question is how can I get the Image from detail["image"]?
I assume that the image contained in detail["image"] is in your application Bundle (i.e.: not an image from an HTTP URL). So, you should use the init(named:) constructor from UIImage to load your image. Something like that:
if let myImage = UIImage(named: detail["image"]) {
myImageView.image = myImage
}
Edit:
Here is, also, your code with a better management of optionals and casts in configureView:
func configureView() {
if let detail = self.detailItem {
if let labelTitle = detail["name"] as? String {
myLabel.text = labelTitle
}
if let textViewContent = detail["someData"] as? String {
myTextView.text = textViewContent
}
if let myImageName = detail["image"] as? String {
if let myImage = UIImage(named: myImageName) {
myImageView.image = myImage
}
}
}
}

Accessing Front Camera in Swift 2.1/iOS 9.1

I am trying to make a selfie app. I am unable to access the front camera. When I run the below code, the app still picks only the back camera.I am working on Xcode 7.1.1. I have also tried it on Xcode 7.2 Beta. Can someone help ? Tried solutions given in the other question here, but that did not solve the problem.
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var previewView: UIView!
#IBOutlet weak var capturedImage: UIImageView!
var captureSession: AVCaptureSession?
var stillImageOutput: AVCaptureStillImageOutput?
var previewLayer: AVCaptureVideoPreviewLayer?
enum AVCaptureDevicePosition : Int {
case Unspecified
case Front
case Back
}
func viewDidAppear(animated: Bool){
super.viewDidAppear(animated)
previewLayer!.frame = previewView.bounds
reloadCamera()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func reloadCamera() {
captureSession = AVCaptureSession()
captureSession!.sessionPreset = AVCaptureSessionPresetPhoto
//let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
// access the front camera
let videoDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
var captureDevice:AVCaptureDevice
for device in videoDevices{
let device = device as AVCaptureDevice
if device.position == AVCaptureDevicePosition.Front {
captureDevice = device
}
}
var error: NSError?
var input: AVCaptureDeviceInput!
do {
input = try AVCaptureDeviceInput(device : captureDevice)
} catch let error1 as NSError {
error = error1
input = nil
}
if error == nil && captureSession!.canAddInput(input) {
captureSession!.addInput(input)
stillImageOutput = AVCaptureStillImageOutput()
stillImageOutput!.outputSettings = [AVVideoCodecKey :AVVideoCodecJPEG]
if captureSession!.canAddOutput(stillImageOutput){
captureSession!.addOutput(stillImageOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
previewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.Portrait
previewView.layer.addSublayer(previewLayer!)
captureSession!.startRunning()
}
}
}
#IBAction func didPressTakePhoto(sender: UIButton) {
if let videoConnection = stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo){
videoConnection.videoOrientation = AVCaptureVideoOrientation.Portrait
stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: {(sampleBuffer, error) in
if (sampleBuffer != nil){
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
let dataProvider = CGDataProviderCreateWithCFData(imageData)
let cgImageRef = CGImageCreateWithJPEGDataProvider(dataProvider,nil,true,CGColorRenderingIntent.RenderingIntentDefault)
let image = UIImage(CGImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.Right)
self.capturedImage.image = image
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
})
}
}
#IBAction func didPressTakeAnother(sender : AnyObject){
captureSession!.startRunning()
}
}

Displaying Artwork for .MP3 file

I am trying to currently display the album artwork for a locally stored .MP3 track in an ImageView. Does anyone know how to fetch this artwork in Swift in order to accomplish this?
I have found this solution (iOS AVFoundation: How do I fetch artwork from an mp3 file?) but the code is written in Objective C. I simply want to grab the image embedded in my MP3 and display it in my ImageView.
I've looked at the API documentation for the MPMediaItemArtwork and found an example that also accomplishes what I am trying to accomplish in Objective C as well here(http://www.codeitive.com/0zHjkUjUWX/not-able-to-get-the-uiimage-from-mpmediaitempropertyartwork.html) but cannot come up with a solution. My code is as follows:
import UIKit
import AVFoundation
import MediaPlayer
class ViewController: UIViewController {
let audioPath:NSURL! = NSBundle.mainBundle().URLForResource("SippinOnFire", withExtension: "mp3")
#IBOutlet var artistImage: UIImageView!
#IBOutlet var trackLabel: UILabel!
#IBOutlet var artistLabel: UILabel!
#IBOutlet var sliderValue: UISlider!
var player:AVAudioPlayer = AVAudioPlayer()
#IBAction func play(sender: AnyObject) {
let audioInfo = MPNowPlayingInfoCenter.defaultCenter()
println(audioInfo)
player.play()
//println("Playing \(audioPath)")
let playerItem = AVPlayerItem(URL: audioPath)
let metadataList = playerItem.asset.metadata as! [AVMetadataItem]
for item in metadataList {
if let stringValue = item.value {
println(item.commonKey)
if item.commonKey == "title" {
trackLabel.text = stringValue as? String
}
if item.commonKey == "artist" {
artistLabel.text = stringValue as? String
}
if item.commonKey == "artwork" {
if let audioImage = UIImage(data: item.value as! NSData) {
let audioArtwork = MPMediaItemArtwork(image: audioImage)
println(audioImage.description)
}
}
}
}
}
#IBAction func pause(sender: AnyObject) {
player.pause()
}
#IBAction func stop(sender: AnyObject) {
player.stop()
player.currentTime = 0;
}
#IBAction func sliderChanged(sender: AnyObject) {
player.volume = sliderValue.value
}
override func viewDidLoad() {
super.viewDidLoad()
var error:NSError? = nil
player = AVAudioPlayer(contentsOfURL: audioPath!, error: &error)
player.volume = 0.5;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is a screen shot of my sample .mp3 file. As you can see there is indeed album artwork that is both visible in the "get info" section of Finder. I've also opened the .mp3 in my iTunes to make sure and have confirmed there is artwork in the "get info" section of it there as well as under the "artwork" tab.
However, when trying to use the commonKey to assign the image to my imageView I find that there is no commonKey for "artwork".
Thanks
Change your snippet of code into this (I already tested it):
I added println lines commented in places of interest, Feel free to uncomment in order to see what is happening.
for item in metadataList {
if item.commonKey == nil{
continue
}
if let key = item.commonKey, let value = item.value {
//println(key)
//println(value)
if key == "title" {
trackLabel.text = value as? String
}
if key == "artist" {
artistLabel.text = value as? String
}
if key == "artwork" {
if let audioImage = UIImage(data: value as! NSData) {
//println(audioImage.description)
artistImage.image = audioImage
}
}
}
}
UPDATE: A bit of clean up of this code
for item in metadataList {
guard let key = item.commonKey, let value = item.value else{
continue
}
switch key {
case "title" : trackLabel.text = value as? String
case "artist": artistLabel.text = value as? String
case "artwork" where value is NSData : artistImage.image = UIImage(data: value as! NSData)
default:
continue
}
}
UPDATE: For Swift 4
for item in metadataList {
guard let key = item.commonKey?.rawValue, let value = item.value else{
continue
}
switch key {
case "title" : trackLabel.text = value as? String
case "artist": artistLabel.text = value as? String
case "artwork" where value is Data : artistImage.image = UIImage(data: value as! Data)
default:
continue
}
}
edit/update Swift 4 or later:
import MediaPlayer
var nowPlayingInfo: [String: Any] = [:]
let playerItem = AVPlayerItem(url: url)
let metadataList = playerItem.asset.metadata
for item in metadataList {
switch item.commonKey {
case .commonKeyTitle?:
nowPlayingInfo[MPMediaItemPropertyTitle] = item.stringValue ?? ""
case .commonKeyType?:
nowPlayingInfo[MPMediaItemPropertyGenre] = item.stringValue ?? ""
case .commonKeyAlbumName?:
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = item.stringValue ?? ""
case .commonKeyArtist?:
nowPlayingInfo[MPMediaItemPropertyArtist] = item.stringValue ?? ""
case .commonKeyArtwork?:
if let data = item.dataValue,
let image = UIImage(data: data) {
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in image }
}
case .none: break
default: break
}
}
let audioInfo = MPNowPlayingInfoCenter.default()
audioInfo.nowPlayingInfo = nowPlayingInfo
Note: You will have to invoke beginReceivingRemoteControlEvents() otherwise it will not work on the actual device. You will also need to set your app Background Modes (Audio and AirPlay) and set your AVAudioSession category to AVAudioSessionCategoryPlayback and set it active:
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay])
print("Playback OK")
try AVAudioSession.sharedInstance().setActive(true)
print("Session is Active")
} catch {
print(error)
}
Try this:
It appears that sometimes iOS 8 returns nil at first attempt of obtaining this info:
if let audioCenter = MPNowPlayingInfoCenter.defaultCenter(){
if let audioInfo = audioCenter.nowPlayingInfo{
if let artwork = audioInfo[MPMediaItemPropertyArtwork] as? MPMediaItemArtwork
{
var image: UIImage? = artwork.imageWithSize(artwork.bounds.size)
if image == nil {
image = artwork.imageWithSize(artwork.bounds.size);
}
if image != nil{
println("image loaded")
}
}
}
}