Saving an image to special album swift - image

I want to add a new photo to certain album, I'm trying to do it like that:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
albumName = "\(data.objectAtIndex(indexPath.row))"
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let actionSheet = UIAlertController(title: "Choose image source", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
actionSheet.addAction(UIAlertAction(title: "Take Photo", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
imagePickerController.sourceType = UIImagePickerControllerSourceType.Camera
self.presentViewController(imagePickerController, animated: true, completion: {})
}))
actionSheet.addAction(UIAlertAction(title: "Camera Roll", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
imagePickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(imagePickerController, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
self.presentViewController(actionSheet, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
let image:UIImage = info[UIImagePickerControllerOriginalImage] as UIImage
var groupToAddTo: ALAssetsGroup = ALAssetsGroup()
self.library.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupAlbum),
usingBlock: {
(group: ALAssetsGroup!, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
if group.valueForProperty(ALAssetsGroupPropertyName).isEqualToString(self.albumName){
groupToAddTo = group
}
},
failureBlock: {
(myerror: NSError!) -> Void in
println("error occurred: \(myerror.localizedDescription)")
})
var img: CGImageRef = image.CGImage
self.library.writeImageToSavedPhotosAlbum(img, metadata: nil, completionBlock: {
(assetUrl: NSURL!, error: NSError!) -> Void in
if error.code == 0 {
println("saved image completed: \(assetUrl)")
self.library.assetForURL(assetUrl, resultBlock: { (asset: ALAsset!) -> Void in
groupToAddTo.addAsset(asset)
return
}, failureBlock: {
(myerror: NSError!) -> Void in
println("error occurred: \(myerror.localizedDescription)")
})
} else {
println("saved image failed. \(error.localizedDescription) code \(error.code)")
}
} )
}
However, when I run this code, I get this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
in this line:
if group.valueForProperty(ALAssetsGroupPropertyName).isEqualToString(self.albumName){
So, the question is that, how to save an image to certain album in swift?

I am betting albumName is an optional value.
You should put an if statement to judge if almbumName is nil. When it's nil, create a newalbum name on your iPhone.

First:
if group != nil {
if group.valueForProperty(ALAssetsGroupPropertyName).isEqualToString(self.albumNames[indexPath.row]){
groupToAddTo = group
}
}
Second, when error = nil your app will crash because of "if error.code == 0." Do "if error == nil" instead.

Related

How to fix error: memory read failed for 0x0

I have clicked login button and the message throw in notification center and a country picker opened and when I click on button in country picker log in view Controller must be opened but it throws an error:
memory read failed for 0x0 ........
this error comes in between obtaining controller object and present.
what should I do now??
I am using Xcode 10.1 and Swift 4
#objc func showSpinningWheel(_ notification: NSNotification) {
if whichbuttonclick == true
{
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.present(vc, animated: true, completion: nil)
}
else
{
self.performSegue(withIdentifier: "Register", sender: self)
}
}
I expect it to jump over login controller but it throws error.
This is how i add Notification Observer :
NotificationCenter.default.addObserver(
self,
selector: #selector(self.showSpinningWheel(:)),
name: Notification.Name(rawValue: "opencontrollermessagenotification"),
object: nil
)
#objc func showSpinningWheel( notification: NSNotification)
{
if whichbuttonclick == true {
self.performSegue(withIdentifier: "Login", sender: self)
} else {
self.performSegue(withIdentifier: "Register", sender: self)
}
}
and This is how i Post it :
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "opencontrollermessagenotification"), object: nil, userInfo: nil)

How to implement UIAlertController in tvOS

I am implementing the UIAlertController in tvOS platform. It's working fine but when i am tap on the button action then the action is not call. But when move up and down with two button and tap any one the action calls.
Here is my code.
func showAlertMessage() {
let alertController = UIAlertController(title: kAlertMessage, message: "", preferredStyle: UIAlertControllerStyle.Alert)
let cancelButton = UIAlertAction(title: kCancelButton, style: UIAlertActionStyle.Default) { (action) -> Void in
self.dismissView()
}
let retryButton = UIAlertAction(title: kRetryButton, style: UIAlertActionStyle.Default) { (action) -> Void in
if self.playerObj != nil{
if self.controlFlag == false {
self.playerItem?.removeObserver(self, forKeyPath: "status")
}else{
self.playerItem?.removeObserver(self, forKeyPath: "status")
}
self.playerObj = nil
self.playerItem = nil
self.asset = nil
}
self.parseJSON()
}
alertController.addAction(retryButton)
alertController.addAction(cancelButton)
if self.alertMessageFlag != true {
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.presentViewController(alertController, animated: true, completion: nil)
}
}
}
please find out the issue and suggest me.
thank you.

In change of Swift 2 Extra argument ' error' in call

Upgrade to Xcode 7 Swift 2 and SDK for iOS 9. I get the error "extra argument" error "in call" my code is:
let myUrl = NSURL(string: "http://localhost/SwiftAppAndMySQL/scripts/registerUser.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let postString = "userEmail=\(userEmail)&userFirstName=\(userFirstName)&userLastName=\(userLastName)&userPassword=\(userPassword)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in
dispatch_async(dispatch_get_main_queue())
{
spinningActivity.hide(true)
if error != nil {
self.displayAlertMessage(error.localizedDescription)
return
}
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var userId = parseJSON["userId"] as? String
if( userId != nil)
{
var myAlert = UIAlertController(title: "Alert", message: "Registration successful", preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default){(action) in
self.dismissViewControllerAnimated(true, completion: nil)
}
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
} else {
let errorMessage = parseJSON["message"] as? String
if(errorMessage != nil)
{
self.displayAlertMessage(errorMessage!)
}
}
}
}
}).resume()
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler ) asks you for 3 optionals arguments and you're giving 3 forceds unwrapping arguments.
try change
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data:NSData!, response:NSURLResponse!, error:NSError!)
to
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?)
Now is working, I replaced the previous code with this::
let myUrl = NSURL(string: "http://dcapp1.testingview.com/DryCleanAppClientes/scripts/registerUser.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let postString = "userEmail=\(userEmail)&userFirstName=\(userFirstName)&userLastName=\(userLastName)&userPassword=\(userPassword)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
print(postString)
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
dispatch_async(dispatch_get_main_queue())
{
spinningActivity.hide(true)
if error != nil {
self.displayAlertMessage(error!.localizedDescription)
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
if let parseJSON = json {
let userId = parseJSON["userId"] as? String
if( userId != nil)
{
let myAlert = UIAlertController(title: "Mensaje", message: "¡Registro exitoso!", preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default){(action) in
self.dismissViewControllerAnimated(true, completion: nil)
}
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
} else {
let errorMessage = parseJSON["message"] as? String
if(errorMessage != nil)
{
self.displayAlertMessage(errorMessage!)
}
}
}
} catch _ as NSError {
}
}
}).resume()
}

EXC_BAD_ACCESS crash on didSelectRowAtIndexPath

My application suddenly started crashing and after four hours I still can't figure out why. It worked perfectly last Friday and I haven't changed anything to the code since.
I have tried:
Stepping through code with breakpoints.
Adding an Exception Breakpoint.
Enabling Zombie objects.
Turning static analyser on.
None of these made me any wiser or pointed me to a more exact error message.
The crash happens when I select a cell. It then points to the AppDelegate with the message "Thread 1: EXC_BAD_ACCESS". Continueing the program execution does not give a more clear error message.
Some images of the error and my code can be seen below. I am really at a loss here so any help will be much appreciated.
Code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
var dealer : DealerList
var alldealer : TotalDealerList
var id : String
if scAll.selectedSegmentIndex == 0
{
if scMatur.selectedSegmentIndex == 0
{
if (self.resultSearchController.active)
{
dealer = filtereddealers[indexPath.row]
}
else
{
dealer = dealers[indexPath.row]
}
}
else
{
if (self.resultSearchController.active)
{
dealer = filtereddealers[indexPath.row]
}
else
{
dealer = sorteddealers[indexPath.row]
}
}
//Create a message box with actions for the user.
let actionSheetController: UIAlertController = UIAlertController(title: "What to do with:", message: "'\(dealer.dlName)'?", preferredStyle: .ActionSheet)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
//Just dismiss the action sheet
}
//starts a phonecall to the selected dealer
let callAction: UIAlertAction = UIAlertAction(title: "Call", style: .Default) { action -> Void in
var phonenr = "0634563859"
let alert2 = UIAlertController(title: "Please confirm", message: "Call '\(dealer.dlName)' at \(phonenr)?", preferredStyle: UIAlertControllerStyle.Alert)
alert2.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.Default, handler: nil))
alert2.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default) { UIAlertAction in
self.callNumber(phonenr)
})
self.presentViewController(alert2, animated: true, completion: nil)
}
//action that opens the DealCustView. Pass data from this view to the next. ID is used in the next view.
let showcustomersAction: UIAlertAction = UIAlertAction(title: "Customers", style: .Default) { action -> Void in
let reportview = self.storyboard?.instantiateViewControllerWithIdentifier("dealcustList") as! DealCustView
reportview.id2 = dealer.dlSCode
reportview.sourceid = self.id
self.navigationController?.pushViewController(reportview, animated: true)
}
//add the actions to the messagebox
actionSheetController.addAction(cancelAction)
actionSheetController.addAction(showcustomersAction)
actionSheetController.addAction(callAction)
//present the messagebox
dispatch_async(dispatch_get_main_queue(), {
self.presentViewController(actionSheetController, animated: true, completion: nil)
})
}
else
{
if scMatur.selectedSegmentIndex == 0
{
if (self.resultSearchController.active)
{
alldealer = filteredalldealers[indexPath.row]
}
else
{
alldealer = alldealers[indexPath.row]
}
}
else
{
if (self.resultSearchController.active)
{
alldealer = filteredalldealers[indexPath.row]
}
else
{
alldealer = sortedalldealers[indexPath.row]
}
}
///
//Create a message box with actions for the user.
let actionSheetController: UIAlertController = UIAlertController(title: "What to do with:", message: "'\(alldealer.tdlName)'?", preferredStyle: .ActionSheet)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
//Just dismiss the action sheet
}
//starts a phonecall to the selected dealer
let callAction: UIAlertAction = UIAlertAction(title: "Call", style: .Default) { action -> Void in
var phonenr = "0634563859"
let alert2 = UIAlertController(title: "Please confirm", message: "Call '\(alldealer.tdlName)' at \(phonenr)?", preferredStyle: UIAlertControllerStyle.Alert)
alert2.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.Default, handler: nil))
alert2.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default) { UIAlertAction in
self.callNumber(phonenr)
})
self.presentViewController(alert2, animated: true, completion: nil)
}
//action that opens the DealCustView. Pass data from this view to the next. ID is used in the next view.
let showcustomersAction: UIAlertAction = UIAlertAction(title: "Customers", style: .Default) { action -> Void in
let reportview = self.storyboard?.instantiateViewControllerWithIdentifier("dealcustList") as! DealCustView
reportview.id2 = alldealer.tdlSCode
reportview.sourceid = self.id
self.navigationController?.pushViewController(reportview, animated: true)
}
//add the actions to the messagebox
actionSheetController.addAction(cancelAction)
actionSheetController.addAction(showcustomersAction)
actionSheetController.addAction(callAction)
//present the messagebox
dispatch_async(dispatch_get_main_queue(), {
self.presentViewController(actionSheetController, animated: true, completion: nil)
})
}
}
}

Display alert keeps logging me out after error message on xcode using swift

I'm creating an Instagram like app, and whenever I dismiss the display alert that is displayed when an image or text is missing, it logs me out and logs me back in. How can I make it so that when I click "ok", only the display alert goes away and doesn't log me out?
Here is my image posting view control code:
import UIKit
import Parse
import Foundation
class PostViewControllerPage1: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
func displayAlert(title:String, error:String) {
var alert = UIAlertController(title: title, message: error, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { action in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
var photoSelected:Bool = false
#IBOutlet weak var imageToPost: UIImageView!
#IBAction func chooseImage(sender: AnyObject) {
var image = UIImagePickerController()
image.delegate = self
image.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
image.allowsEditing = false
self.presentViewController(image, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
println("Image selected")
self.dismissViewControllerAnimated(true, completion: nil)
imageToPost.image = image
photoSelected = true
}
#IBOutlet weak var imageDescription: UITextField!
#IBAction func postImage(sender: AnyObject) {
var error = ""
if (photoSelected == false) {
error = "Please select an image to post"
} else if (imageDescription.text == "") {
error = "Please enter a message"
}
if (error != "") {
displayAlert("Cannot Post Image", error: error)
}
else {
var post = PFObject(className: "Post")
post["Title"] = imageDescription.text
post.saveInBackgroundWithBlock{(success: Bool, error: NSError?) -> Void in
if success == false {
self.displayAlert("Could Not Post Image", error: "Please try again later")
} else {
let imageData = UIImagePNGRepresentation(self.imageToPost.image)
let imageFile = PFFile(name: "image.png", data: imageData)
post["imageFile"] = imageFile
post.saveInBackgroundWithBlock{(success: Bool, error: NSError?) -> Void in
if success == false {
self.displayAlert("Could Not Post Image", error: "Please try again later")
} else {
println("posted successfully")
}
}
}
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
What am I doing wrong?
Here is my login code, because I feel like that might be a part of the issue:
import Foundation
import Parse
import UIKit
import Bolts
class LoginViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var loginStatusLabel: UILabel!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
#IBOutlet weak var loginButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
emailTextField.delegate = self
passwordTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func loginButtonPress(sender: AnyObject) {
login(emailTextField.text, password: passwordTextField.text)
}
func login(email: String, password: String)
{
PFUser.logInWithUsernameInBackground(email, password: password)
{
(user: PFUser?, error: NSError?) -> Void in
if user != nil
{
user!.fetchInBackground()
if user!.objectForKey("emailVerified") as! Bool
{
self.loginStatusLabel.text = "Success!"
println("successfulLogin")
self.performSegueWithIdentifier("login", sender: self)
}
else if !(user!.objectForKey("emailVerified") as! Bool)
{
self.loginStatusLabel.text = "Verify your email address!"
}
else // status is "missing"
{
//TODO: Handle this error better
self.loginStatusLabel.text = "Verification status: Missing"
}
}
else
{
if let errorField = error!.userInfo
{
self.loginStatusLabel.text = (errorField["error"] as! NSString) as String
}
else
{
// No userInfo dictionary present
// Help from http://stackoverflow.com/questions/25381338/nsobject-anyobject-does-not-have-a-member-named-subscript-error-in-xcode
}
}
}
}
override func viewDidAppear(animated: Bool) {
if PFUser.currentUser() != nil {
self.performSegueWithIdentifier("login", sender: self)
}
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true;
}
override func viewWillAppear(animated: Bool) {
self.navigationController?.navigationBarHidden = true
}
override func viewWillDisappear(animated: Bool) {
self.navigationController?.navigationBarHidden = false
}
}
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { action in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.dismissViewControllerAnimated in this line will dismiss view controller that show alert and not an alert itself. So all you have to do is comment or delete this line of code

Resources