Adding Photos to Array and Displaying to UICollection View error - swift

QUESTION
This code works to set an image to an array but comes up with the following error - 2017-12-06 12:31:21.264812+0000 SmartReceipts[880:172369] [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}
I need to know what this means and if there is a possible fix around it?
import UIKit
class GalleryController: UICollectionViewController,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
var Receipts = [UIImage?]()
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView?.reloadData()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
//self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
self.dismiss(animated: true, completion: nil)
print(info);
let newReceipts = info[UIImagePickerControllerEditedImage] as? UIImage
self.Receipts.append(newReceipts)
print("Array Contains \(self.Receipts.count) Receipts")
print(self.Receipts)
self.collectionView?.reloadData()
print("completedIfStatement")
}
#IBAction func getReceipts(_ sender: Any) {
print("PlusButtonPressed")
let optionMenu = UIAlertController(title: nil, message: "Choose Option", preferredStyle: .actionSheet)
// 2
let albumAction = UIAlertAction(title: "Album", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
print("PhotosOption")
self.getFromReceipts()
})
let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
print("CameraOption")
self.getFromCamera()
})
//
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancel")
})
// 4
optionMenu.addAction(albumAction)
optionMenu.addAction(cameraAction)
optionMenu.addAction(cancelAction)
// 5
self.present(optionMenu, animated: true, completion: nil)
}
func getFromReceipts() {
print("GetFromReceipts")
let cameraPicker = UIImagePickerController()
cameraPicker.delegate = self
cameraPicker.sourceType = .photoLibrary
self.present(cameraPicker, animated: true, completion: nil )
}
func getFromCamera() {
print("GetFromCamera")
let cameraPicker = UIImagePickerController()
cameraPicker.delegate = self
cameraPicker.sourceType = .camera
self.present(cameraPicker, animated: true, completion: nil )
}
//Number of Views
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.Receipts.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtindexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Receipts, for: indexPath as IndexPath) as? PhotoCell
cell?.imageView.image = self.Receipts[indexPath.row]
return cell!
}
}

The error maybe comes from not requesting the authorization to load an photo from the camera or the photo library. So you need to request for authorization before opening the camera like:
https://developer.apple.com/documentation/photos/phphotolibrary/1620736-requestauthorization

I guess you'r not requesting Photo/Camera authorizations.
You have to add the below keys to Info.plist.
Camera permission :
<key>NSCameraUsageDescription</key>
<string> ${PRODUCT_NAME} Camera Usage< </string>
For Photo Library, you will want this one to allow app user to browse the photo library.
<key>NSPhotoLibraryUsageDescription</key>
<string>${PRODUCT_NAME} Photo Usage</string>
And in you'r source code, to ask permission for the photo/camera you need to add this code (Swift 3):
PHPhotoLibrary.requestAuthorization({
(newStatus) in
if newStatus == PHAuthorizationStatus.authorized {
/* do stuff here */
}
})

Related

How can I save multiple images which are picked from the UIPickerController?

All the images which I'm uploading in the app (with the UIImagePickerController) are showing in the app but when I'm closing the app the images disappear. I used UserDefaults for one image (without the UICollectionView) and the code worked (see the code) but when i used the UICollectionView, the code does not work anymore. It would be nice if anyone can help me or give me some tips!
import UIKit
class wardrobeViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var allImagesCollection: UICollectionView!
var collectionViewClass = CollectionViewCell()
var theUploadedImg = UIImageView()
let userDefault = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
allImagesCollection.delegate = self
allImagesCollection.dataSource = self
collectionViewClass.newImage = theUploadedImg
let imageData = userDefault.object(forKey: "thePickedImage") as? NSData
if let imageData = imageData {
let image = UIImage(data: imageData as Data)
theUploadedImg.image = image
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func chooseImage(_ sender: Any) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let actionSheet = UIAlertController(title: "", message: "Choose an image from", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action: UIAlertAction) in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
imagePickerController.sourceType = UIImagePickerControllerSourceType.camera
imagePickerController.allowsEditing = false
self.present(imagePickerController, animated: true, completion: nil)
}
}))
actionSheet.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action: UIAlertAction) in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
imagePickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePickerController.allowsEditing = false
self.present(imagePickerController, animated: true, completion: nil)
}
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
var newPickedImage = [UIImage]()
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
theUploadedImg.contentMode = .scaleToFill
theUploadedImg.image = pickedImage
newPickedImage.append(pickedImage)
let pickedImageData = UIImagePNGRepresentation(pickedImage)
userDefault.set(pickedImageData, forKey: "thePickedImage")
}
picker.dismiss(animated: true, completion: nil)
allImagesCollection.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return newPickedImage.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
cell.newImage.image = newPickedImage[indexPath.item]
cell.layer.borderColor = UIColor.lightGray.cgColor
cell.layer.borderWidth = 0.5
return cell
}
let cellsPerRow = 3
override func viewWillLayoutSubviews() {
guard let collectionView = allImagesCollection, let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return }
let marginsAndInsets = flowLayout.sectionInset.left + flowLayout.sectionInset.right + collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right + flowLayout.minimumInteritemSpacing * CGFloat(cellsPerRow - 1)
let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down)
flowLayout.itemSize = CGSize(width: itemWidth, height: itemWidth)
}
}
You are saving only 1 image to UserDefaults. In order to persist these images, you have to save all of them, not just override 1 image. Also, on application start you have to fetch all of the images and reload UICollectionView with them.
One more tip, do not save images to UserDefaults, use FileManager.

Long press gesture action sheet delete cell

I trying to code long press gesture on the cell in collection view but I haven't found about similar... I suppose I do to code something in the 'didSelectItemAt'.
Now works only if I tap in the first cell...
And then I have found on web to different solution based on swift 3.
Every one help me please? Thank you so much!
The image show when tap long on the first cell the action sheet. But don't work when I tap to other cell...
import UIKit
class RecipeCollViewController: UICollectionViewController, UITextFieldDelegate
{
struct Storyboard
{
static let leftAndRightPaddings: CGFloat = 2.0
static let numberOfItemsPerRow: CGFloat = 2.0
}
override func viewDidLoad() {
super.viewDidLoad()
RecipeDataManager.shared.recipeController = self
title = loc("TITLE_RECIPECOLL")
navigationController?.navigationBar.prefersLargeTitles = true
let collectionViewWidth = collectionView?.frame.width
let itemWidth = (collectionViewWidth! - Storyboard.leftAndRightPaddings) / Storyboard.numberOfItemsPerRow
let layout = collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: itemWidth, height: 250)
}
override func numberOfSections(in collectionView: UICollectionView) -> Int
{
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return RecipeDataManager.shared.recipes.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RecipeCell", for: indexPath) as! RecipeViewCell
let recipe = RecipeDataManager.shared.recipes[indexPath.item]
cell.labelNameRecipe.text = recipe.titleRecipe
cell.imageViewRecipe.image = recipe.imageRecipe
cell.labelPrepareTime.text = String(recipe.recipeTimeInt)
cell.labelPeopleFor.text = recipe.peopleRecipe
return cell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
}
// MARK: - NAVIGAZIONE
// Metodo che scatta quando l'utente tocca una delle celle della collectionView e apre il dettaglio
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "RecipeDetail"
{
if let indexPath = self.collectionView!.indexPathsForSelectedItems?.first
{
let recipeDetailVC = segue.destination as! DetailRecipeViewController
recipeDetailVC.recipe = RecipeDataManager.shared.recipes[indexPath.item]
}
}
}
// MARK: - UILongPressGestureRecognizer function for the cell recipe
#IBAction func popUpActionCell(longPressGesture : UILongPressGestureRecognizer)
{
let alertActionCell = UIAlertController(title: "Action Recipe Cell", message: "Choose an action for the selected recipe", preferredStyle: .actionSheet)
// Configure Remove Item Action
let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { action in
// Delete selected Cell
let deleteRecipe: [RecipeDataManager] = []
if let indexPath = self.collectionView?.indexPathsForSelectedItems?.first
{
RecipeDataManager.shared.recipes.remove(at: indexPath.item)
RecipeDataManager.shared.salva()
self.collectionView?.deleteItems(at: [indexPath])
}
print("Cell Removed")
})
// Configure Cancel Action Sheet
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { acion in
print("Cancel actionsheet")
})
alertActionCell.addAction(deleteAction)
alertActionCell.addAction(cancelAction)
self.present(alertActionCell, animated: true, completion: nil)
self.collectionView!.reloadData()
}
}
With my pleausure, I have found the finally solution at my problem.
Post the code for other new developer needs help!
// MARK: - Long Press Gesture Action Sheet
#IBAction func popUpActionCell(longPressGesture : UILongPressGestureRecognizer)
{
// Delete selected Cell
let point = longPressGesture.location(in: self.collectionView)
let indexPath = self.collectionView?.indexPathForItem(at: point)
// let cell = self.collectionView?.cellForItem(at: indexPath!)
if indexPath != nil
{
let alertActionCell = UIAlertController(title: "Action Recipe Cell", message: "Choose an action for the selected recipe", preferredStyle: .actionSheet)
// Configure Remove Item Action
let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { action in
RecipeDataManager.shared.recipes.remove(at: indexPath!.row)
print("Cell Removed")
self.collectionView!.reloadData()
})
// Configure Cancel Action Sheet
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { acion in
print("Cancel actionsheet")
})
alertActionCell.addAction(deleteAction)
alertActionCell.addAction(cancelAction)
self.present(alertActionCell, animated: true, completion: nil)
}
}

Update a collection view in an other view

For school I have to make an iOS application. I would like to use an UICollectionView in an other View. I use the following code, but when I use self.libraryCollectionView.reloadData(), the collectionView function is not called. The CollectionView with the name libraryCollectionView should hold an gallery of Images.
Here you can see the code I wrote.
import UIKit
class CoverViewController: UIViewController, UICollectionViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UICollectionViewDataSource {
// MARK: Properties
#IBOutlet weak var photoImageView: UIImageView!
#IBOutlet weak var typeLabel: UILabel!
#IBOutlet weak var libraryCollectionView: UICollectionView!
var cover: Cover?
var images = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
// Set up views if editing an existing Cover.
if let cover = cover {
photoImageView.image = cover.image
typeLabel.text = cover.type
}
libraryCollectionView.delegate = self
libraryCollectionView.dataSource = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
#IBAction func addImage(_ sender: UIBarButtonItem) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet);
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action) in
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
imagePicker.sourceType = .photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// Methods for ImagePicker
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
images.append(pickedImage)
DispatchQueue.main.async{
self.libraryCollectionView.reloadData()
}
}
dismiss(animated: true, completion: nil)
}
// Methods for CollectionView
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 0
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellIdentifier = "cell"
let cell = libraryCollectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ImageCellView
NSLog(String(images.count))
cell.photoImageView.image = images[indexPath.row]
return cell
}
}
numberOfSections(in collectionView: UICollectionView) should return at least 1.
It's default value is also 1, so you can just delete the whole method from your code.

Cannot convert value of type "[(title: String, description : String, pubDate : String, link : String)]?" to type 'NSArray' in coercion

class NewsViewController: UITableViewController, UISearchResultsUpdating {
var rssItems : [(title: String, description : String, pubDate : String, link : String)]?
var filteredRssItems = [String]()
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.separatorColor = UIColor.clearColor()
self.view.backgroundColor = UIColor(colorLiteralRed: 1.4, green: 1.4, blue: 1.4, alpha: 1)
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let feedParser = FeedParser()
feedParser.parseFeed("http://rss.etnews.co.kr/Section902.xml", completionHandler: { (rssItems: [(title: String, description: String, pubDate: String, link: String)]) -> Void in
self.rssItems = rssItems
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.tableView.reloadSections(NSIndexSet(index: 0), withRowAnimation: .None)
})
})
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let rssItems = rssItems else {
return 0
}
if (self.resultSearchController.active) {
return self.filteredRssItems.count
} else {
return rssItems.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! NewsTableViewCell
if (self.resultSearchController.active) {
cell.titleLabel.text = filteredRssItems[indexPath.row]
cell.descriptionLabel.text = filteredRssItems[indexPath.row]
cell.dateLabel.text = filteredRssItems[indexPath.row]
} else {
cell.titleLabel.text = rssItems![indexPath.row].title
cell.descriptionLabel.text = rssItems![indexPath.row].description
cell.dateLabel.text = rssItems![indexPath.row].pubDate
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let item = rssItems?[indexPath.row]
if let url = NSURL(string: item!.link) {
let safariController = SFSafariViewController(URL: url, entersReaderIfAvailable: true)
presentViewController(safariController, animated: true, completion: nil)
}
tableView.deselectRowAtIndexPath(indexPath, animated: false)
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 190.0
}
#IBAction func shartBtnTapped(sender: AnyObject) {
let actionSheet = UIAlertController(title: "", message: "Share your Note", preferredStyle: UIAlertControllerStyle.ActionSheet)
// Configure a new action for sharing the note in Twitter.
let tweetAction = UIAlertAction(title: "Share on Twitter", style: UIAlertActionStyle.Default) { (action) -> Void in
}
// Configure a new action to share on Facebook.
let facebookPostAction = UIAlertAction(title: "Share on Facebook", style: UIAlertActionStyle.Default) { (action) -> Void in
}
// Configure a new action to show the UIActivityViewController
let moreAction = UIAlertAction(title: "More", style: UIAlertActionStyle.Default) { (action) -> Void in
let activityViewController = UIActivityViewController(activityItems: [self.title!], applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivityTypeMail]
self.presentViewController(activityViewController, animated: true, completion: nil)
}
let dismissAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.Cancel) { (action) -> Void in
}
actionSheet.addAction(tweetAction)
actionSheet.addAction(facebookPostAction)
actionSheet.addAction(moreAction)
actionSheet.addAction(dismissAction)
presentViewController(actionSheet, animated: true, completion: nil)
}
func showAlertMessage(message: String!) {
let alertController = UIAlertController(title: "EasyShare", message: message, preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.Default, handler: nil))
presentViewController(alertController, animated: true, completion: nil)
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.filteredRssItems.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (self.rssItems as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredRssItems = array as! [String]
self.tableView.reloadData()
}
#IBAction func logoutBtnTapped(sender: AnyObject) {
NSUserDefaults.standardUserDefaults().setValue(nil, forKey: "uid")
self.dismissViewControllerAnimated(true, completion: nil)
}
please help me~ i have a problem.
let array = (self.rssItems as NSArray).filteredArrayUsingPredicate(searchPredicate) => Cannot convert value of type “[(title: String, description : String, pubDate : String, link : String)]?” to type 'NSArray' in coercion
please advice me solution~
NSArrays can only contain types conforming to AnyObject. A tuple is not an AnyObject, and as such cannot be stored in an NSArray.
I see, however, that you cast the result of the filter to [String]. Do you perhaps mean to extract one of the entries in the tuple before applying the filter? For example, something like:
let array = (self.rssItems.map({ $0.description }) as NSArray).filteredArrayUsingPredicate(searchPredicate)
If not, you may have to consider an alternative to filteredArrayUsingPredicate. Consider instead using a Swift Array and filter with your own filtering function.

performSegueWithIdentifier not always working in Swift

I've got a UITableView with a few cells on there and I want to segue to another screen whenever I push one of these cells. My code works, sort of.... But sometimes I've to push the cell twice in order to segue!
Does anyone know why?
func tableView(gamesListTableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if (indexPath.row < GamesList.count) {
self.gameState = GamesList[indexPath.row];
performSegueWithIdentifier("presentGame", sender: self);
} else {
let alert = UIAlertController(title: "Swipe!", message: "Swipe Invite To The Left", preferredStyle: UIAlertControllerStyle.Alert)
let alertAction = UIAlertAction(title: "OK!", style: UIAlertActionStyle.Default) { (UIAlertAction) -> Void in }
alert.addAction(alertAction)
presentViewController(alert, animated: true) { () -> Void in }
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "presentGame") {
var presentGame = segue.destinationViewController as! Game;
presentGame.gameState = self.gameState;
}
}
There is known issue in the wild that require dummy dispatch_async call as workaround - http://openradar.appspot.com/19563577 likely in future versions it will go away. Here is how code with a workaround will looks like:
func tableView(gamesListTableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if (indexPath.row < GamesList.count) {
self.gameState = GamesList[indexPath.row];
dispatch_async(dispatch_get_main_queue(), {}); //http://openradar.appspot.com/19563577
performSegueWithIdentifier("presentGame", sender: self);
} else {
let alert = UIAlertController(title: "Swipe!", message: "Swipe Invite To The Left", preferredStyle: UIAlertControllerStyle.Alert)
let alertAction = UIAlertAction(title: "OK!", style: UIAlertActionStyle.Default) { (UIAlertAction) -> Void in }
alert.addAction(alertAction)
presentViewController(alert, animated: true) { () -> Void in }
}
}