How do I fetch images from photo library? - swift3

Hi I had switch from swift 2 to swift 3.
Here is my uploadVC
class PhotoUploadVC: UICollectionViewController {
fileprivate var assets: PHFetchResult<AnyObject>?
fileprivate var sideSize: CGFloat!
//It is snippet of viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
//Navigation Config
self.navigationItem.title = "CAMERA ROLL"
if PHPhotoLibrary.authorizationStatus() == .authorized {
reloadAssets()
} else {
PHPhotoLibrary.requestAuthorization({ (status: PHAuthorizationStatus) -> Void in
if status == .authorized {
self.reloadAssets()
} else {
self.showNeedAccessMessage()
}
})
}
}
//Here is function about fetch images
fileprivate func showNeedAccessMessage() {
let alert = UIAlertController(title: "Image picker", message: "App need get access to photos", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction) -> Void in
self.dismiss(animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction) -> Void in
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}))
self.show(alert, sender: nil)
}
fileprivate func reloadAssets() {
// activityIndicator.startAnimating()
assets = nil
collectionView?.reloadData()
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
assets = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
collectionView?.reloadData()
// activityIndicator.stopAnimating()
}
I got an error message above.
Where is problem?
I think "fileprivate var assets: PHFetchResult?"
Anyone helping me?

Try changing:
fileprivate var assets: PHFetchResult<AnyObject>?
into
var assets: [AnyObject]!

Related

SKStoreProductViewController must be used in a modal view controller SWIFTUI

I am building a info page for my SwiftUI app. One item should open App Store, another mail. I have written UIViewControllerRepresentable for each.
MailView works fine totally. StoreView displays fine, but when pressed on Cancel button, throws exception
"*** Terminating app due to uncaught exception 'SKUnsupportedPresentationException', reason: 'SKStoreProductViewController must be used in a modal view controller'".
MailView goes fine into didFinish delegate method but StoreView does not go into didFinish delegate method, it crashes before going into this didFinish method. What am I doing wrong please?
import SwiftUI
import StoreKit
import MessageUI
struct InfoMoreAppsView: View {
#State var showAppAtStore = false
#State var reportBug = false
#State var result: Result<MFMailComposeResult, Error>? = nil
let otherAppName = "TheoryTest"
var body: some View {
VStack(alignment: .leading){
HStack{
Image(Helper.getOtherAppImageName(otherAppName: otherAppName))
Button(action: { self.showAppAtStore = true }) {
Text(otherAppName)
}
.sheet(isPresented: $showAppAtStore){
StoreView(appID: Helper.getOtherAppID(otherAppName: otherAppName))
}
}
Button(action: { self.reportBug = true }) {
Text("Report a bug")
}
.sheet(isPresented: $reportBug){
MailView(result: self.$result)
}
}
.padding()
.font(.title2)
}
}
struct StoreView: UIViewControllerRepresentable {
let appID: String
#Environment(\.presentationMode) var presentation
class Coordinator: NSObject, SKStoreProductViewControllerDelegate {
#Binding var presentation: PresentationMode
init(presentation: Binding<PresentationMode> ) {
_presentation = presentation
}
private func productViewControllerDidFinish(viewController: SKStoreProductViewController) {
$presentation.wrappedValue.dismiss()
viewController.dismiss(animated: true, completion: nil)
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(presentation: presentation)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<StoreView>) -> SKStoreProductViewController {
let skStoreProductViewController = SKStoreProductViewController()
skStoreProductViewController.delegate = context.coordinator
let parameters = [ SKStoreProductParameterITunesItemIdentifier : appID]
skStoreProductViewController.loadProduct(withParameters: parameters)
return skStoreProductViewController
}
func updateUIViewController(_ uiViewController: SKStoreProductViewController, context: UIViewControllerRepresentableContext<StoreView>) {
}
}
struct MailView: UIViewControllerRepresentable {
#Environment(\.presentationMode) var presentation
#Binding var result: Result<MFMailComposeResult, Error>?
class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
#Binding var presentation: PresentationMode
#Binding var result: Result<MFMailComposeResult, Error>?
init(presentation: Binding<PresentationMode>,
result: Binding<Result<MFMailComposeResult, Error>?>) {
_presentation = presentation
_result = result
}
func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?) {
defer {
$presentation.wrappedValue.dismiss()
}
guard error == nil else {
self.result = .failure(error!)
return
}
self.result = .success(result)
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(presentation: presentation,
result: $result)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> MFMailComposeViewController {
let mailComposeViewController = MFMailComposeViewController()
mailComposeViewController.mailComposeDelegate = context.coordinator
mailComposeViewController.setToRecipients([Constants.SUPPORT_EMAIL])
mailComposeViewController.setMessageBody(systemInfo(), isHTML: true)
return mailComposeViewController
}
func systemInfo() -> String {
let device = UIDevice.current
let systemVersion = device.systemVersion
let model = UIDevice.hardwareModel
let mailBody = "Model: " + model + ". OS: " + systemVersion
return mailBody
}
func updateUIViewController(_ uiViewController: MFMailComposeViewController,
context: UIViewControllerRepresentableContext<MailView>) {
}
}
This isn't very "Swifty" or pretty but I got this to work without crashing by not wrapping the SKStoreProductViewController in a representable.
struct MovieView: View {
var vc:SKStoreProductViewController = SKStoreProductViewController()
var body: some View {
HStack(){
Button(action: {
let params = [
SKStoreProductParameterITunesItemIdentifier:"1179624268",
SKStoreProductParameterAffiliateToken:"11l4Cu",
SKStoreProductParameterCampaignToken:"hype_movie"
] as [String : Any]
// vc!.delegate = self
vc.loadProduct(withParameters: params, completionBlock: { (success,error) -> Void in
UIApplication.shared.windows.first?.rootViewController?.present(vc, animated: true, completion: nil)
})
}) {
HStack {
Image(systemName: "play.fill")
.font(.headline)
}
.padding(EdgeInsets(top: 6, leading:36, bottom: 6, trailing: 36))
.foregroundColor(.white)
.background(Color(red: 29/255, green: 231/255, blue: 130/255))
.cornerRadius(10)
}
Spacer()
}}
Since I was stuck on the same thing. Here is a quick solution I found working.
import StoreKit
import SwiftUI
import UIKit
struct StoreView: UIViewControllerRepresentable {
var dismissHandler: () -> Void
func makeUIViewController(context: UIViewControllerRepresentableContext<StoreView>) -> StoreViewController {
return StoreViewController(coordinator: context.coordinator)
}
func updateUIViewController(_ uiViewController: StoreViewController, context: UIViewControllerRepresentableContext<StoreView>) {
}
public func makeCoordinator() -> StoreViewCoordinator {
.init(dismissHandler: dismissHandler)
}
}
class StoreViewController: UIViewController {
let coordinator: StoreViewCoordinator
var storeController: SKStoreProductViewController?
init(coordinator: StoreViewCoordinator) {
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
}
#available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
storeController = SKStoreProductViewController()
storeController?.delegate = coordinator
storeController?.loadProduct(
withParameters: [SKStoreProductParameterITunesItemIdentifier: ******]
)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
guard let storeController = storeController else {
return
}
present(storeController, animated: true)
}
}
class StoreViewCoordinator: NSObject, SKStoreProductViewControllerDelegate {
private let dismissHandler: () -> Void
init(dismissHandler: #escaping () -> Void) {
self.dismissHandler = dismissHandler
}
func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
dismissHandler()
}
}
and then I am using it inside ZStack like:
StoreView(
dismissHandler: { viewStore.send(.setShowingStore(false)) }
)
.isHidden(!viewStore.isShowingStore, remove: true)
I am using TCA, so setting a property will be different in your case

After dismiss the imagePickerController, how to go back to the current tab instead of the default tab

I have 4 tabs in the tab bar. Currently, I am working in the 4th tab, and having an imagePickerController. After the imagePickerController dismissed, it goes to the default tab (1st tab). How can I make it go to the current (4th) tab?
class EditMyPostViewController: UIViewController {
#IBOutlet weak var postImageView: UIImageView!
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
#IBAction func updatePhotoTapped(_ sender: Any) {
let alert = UIAlertController(title: "Add a picture", message: "How do you want to upload the picture?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Take Photo", style: .default, handler: { action in
self.takePhotoWithCamera()
}))
alert.addAction(UIAlertAction(title: "Use Existing Photo", style: .default, handler: { action in
self.getPhotoFromLibrary()
}))
self.present(alert, animated: true)
}
}
extension EditMyPostViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func takePhotoWithCamera() {
if (!UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera)) {
let alertController = UIAlertController(title: "No Camera", message: "The device has no camera.", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(okAction)
present(alertController, animated: true, completion: nil)
} else {
imagePicker.allowsEditing = false
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
}
func getPhotoFromLibrary() {
imagePicker.allowsEditing = false
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
{
postImageView.image = image
}
dismiss(animated: true, completion: nil)
}
}
The imagePicker is present in the 2 functions takePhotoWithCamera() and getPhotoFromLibrary().
In the last function, I tried to dismiss(animated: true, completion: nil), but it goes to the default tab instead of the current tab. How can I present the current ViewController?
I tried
present(self, animated: true, completion: nil)
But it will cause an Exception: Application tried to present modally an active controller

Creating an image format with an unknown type is an error UIImagePickerController() , unexpectedly found nil

Swift Version 3
Xcode Version 8.3.3 (8E3004b)
This question has been asked and answered before. Yet, I cannot find a way fix this error.
"Creating an image format with an unknown type is an error" with UIImagePickerController
When a new picture is selected from Photo Library, I get this error
Generic Creating an image format with an unknown type is an error.
I select the photo and when I tap choose, I get error in func takePhoto where I do this assignment self?.imgView.image = newImage
fatal error: unexpectedly found nil while unwrapping an Optional value
Printing description of newImage: expression produced error: error:
/var/folders/s0/xq_zc7l56m1__n1qjk29p6tw0000gn/T/./lldb/2631/expr1.swift:1:80:
error: use of undeclared type 'UIKit'
Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer>(bitPattern:
0x118055200)!.pointee)
^~~~~
typealias imagePickerHelperCompletion = ((UIImage?) -> Void)!
class ImagePickerHelper: NSObject {
weak var viewController: UIViewController!
var cameraFlashMode: UIImagePickerControllerCameraFlashMode //flash, no flash
var photoLibraryIsVisible: Bool
var cameraDevice: UIImagePickerControllerCameraDevice //front, back camera
var completion: imagePickerHelperCompletion
init(viewController: UIViewController, cameraFlashMode:UIImagePickerControllerCameraFlashMode, photoLibraryIsVisible: Bool,cameraDevice: UIImagePickerControllerCameraDevice, completion: imagePickerHelperCompletion) {
self.viewController = viewController
self.completion = completion
self.cameraFlashMode = cameraFlashMode
self.photoLibraryIsVisible = photoLibraryIsVisible
self.cameraDevice = cameraDevice
//super.init() implemented by subclasses to initializer a new object (the receiver) immediately after memory has been allocated
super.init()
self.showPhotoSourceSelection()
}
//show camera or photo library
func showPhotoSourceSelection() {
let actionSheet = UIAlertController(title: "Take new photo", message: "Would you like to open \n Camera or Photo Library?", preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default) { (action) in
self.showImagePicker(sourceType: .camera)
}
let photoLibraryAction = UIAlertAction(title: "Photo Library", style: .default) { (action) in
self.showImagePicker(sourceType: .photoLibrary)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in }
actionSheet.addAction(cameraAction)
if photoLibraryIsVisible == true { actionSheet.addAction(photoLibraryAction) }
actionSheet.addAction(cancelAction)
viewController.present(actionSheet, animated: true, completion: nil)
}
func showImagePicker(sourceType: UIImagePickerControllerSourceType) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true //user can crop the image, or do some editing
imagePicker.sourceType = sourceType
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.delegate = self
if imagePicker.sourceType == .camera {
imagePicker.cameraFlashMode = cameraFlashMode
imagePicker.cameraDevice = self.cameraDevice
}
viewController.present(imagePicker, animated: true, completion: nil)
}
}//end of class
extension ImagePickerHelper: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
viewController.dismiss(animated: true, completion: nil)
}
//if user did take a photo
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print(info)
//prints out ["UIImagePickerControllerEditedImage": <UIImage: 0x610000294320> size {746, 498} orientation 0 scale 1.000000, "UIImagePickerControllerMediaType": public.image, "UIImagePickerControllerCropRect": NSRect: {{0, 0}, {2661, 1779}}, "UIImagePickerControllerReferenceURL": assets-library://asset/asset.JPG?id=ED7AC36B-A150-4C38-BB8C-B6D696F4F2ED&ext=JPG, "UIImagePickerControllerOriginalImage": <UIImage: 0x610000299320> size {2668, 1780} orientation 0 scale 1.000000]
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
completion(image)
viewController.dismiss(animated: true, completion: nil)
} else if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
viewController.dismiss(animated: true, completion: nil)
completion(image)
} else {
print("something is wrong line \(#line)")
}
}
}//end of extension
class ProfileViewController: UITableViewController {
var imagePickerHelper: ImagePickerHelper!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func takePhoto(_ sender: Any) {
//create instance of ImagePickerHelper and take photo, or get it from photoLibrary
imagePickerHelper = ImagePickerHelper( viewController: self, cameraFlashMode: .auto,photoLibraryIsVisible: true, cameraDevice: .front,
completion: { [weak self] (newImage) in
})
}
}//end of class

UILabel data to UIAlert issue in xcode 8, error

I made an alert and I tried to follow a tutorial and put it into my code. I put the code in a few different places but the errors just kept getting worse. I finally just put it at the bottom, because thats where I ended up getting the fewest errors. I'm new to xcode so this very basic thing is very hard for me. Furthermore, I get errors all over the place when I put this in, and I have no idea how to fix this. Moreover, what I am trying to do is take the data that is being saved in my UILabel which is a name, and I want that to be shown up in the clickable part of the alert that "dismisses" the alert, but I have no idea how to do that or even get started when I can't add a basic alert into my code. Any help would be great source code even better. Sorry for all the questions. Thanks again in advance.
import UIKit
import MultipeerConnectivity
class ViewController: UIViewController, MCBrowserViewControllerDelegate {
#IBOutlet weak var input: UITextField!
#IBOutlet weak var output: UILabel!
#IBAction func action(_ sender: Any) {
output.text = input.text
UserDefaults.standard.set(input.text, forKey: "MyName")
input.text = ""
}
var currentPlayer:String!
var appDelegate:AppDelegate!
override func viewDidLoad() {
super.viewDidLoad()
appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.MPCHandler.setupPeerWithDisplayName(UIDevice.current.name)
appDelegate.MPCHandler.setupSession()
appDelegate.MPCHandler.advertiseSelf(true)
NotificationCenter.default.addObserver(self, selector: Selector(("peerChangedStateWithNotification:")), name: NSNotification.Name(rawValue: "MPC_DidChangeStateNotification"), object: nil)
NotificationCenter.default.addObserver(self, selector: Selector(("handleReceivedDataWithNotification:")), name: NSNotification.Name(rawValue: "MPC_DidReceiveDataNotification"), object: nil)
}
#IBAction func connect(_ sender: Any) {
if appDelegate.MPCHandler.session != nil{
appDelegate.MPCHandler.setupBrowser()
appDelegate.MPCHandler.browser.delegate = self
self.present(appDelegate.MPCHandler.browser, animated: true, completion: nil)
}
}
func peerChangedStateWithNotification(notification:NSNotification){
let userInfo = NSDictionary(dictionary: notification.userInfo!)
let state = userInfo.object(forKey: "state") as! Int
if state != MCSessionState.connecting.rawValue{
self.navigationItem.title = "Connected"
}
}
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
appDelegate.MPCHandler.browser.dismiss(animated: true, completion: nil)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
appDelegate.MPCHandler.browser.dismiss(animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(_ animated: Bool) {
if let x = UserDefaults.standard.object(forKey:"myName") as?
String
{
output.text = x
}
}
}
func viewDidAppear(_animated: Bool) {
createAlert(title: "HI", message: "ARE YOU READY")
}
func createAlert (title: String, message:String)
{
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "HI", style: UIAlertActionStyle.default, handler: { (action) in alert.dismiss(animated: true, completion: nil);))
self.present(alert,animated: true, completion:nil)
}
}
The error you are most probably getting is Invalid redeclaration of 'viewDidAppear' means you are trying to add viewDidAppear method twice in your ViewController. So remove the below one method form your code and call createAlert inside the already exist viewDidAppear one.
Your second mistake is you forgot to add } for UIAlertActionHandler and there is no need to call dismiss on alert action it will automatically dismiss the alert.
You need to also change your selector syntax to Swift3 one and also you forgot to add handleReceivedDataWithNotification with your code.
Now with Swift use Swift native dictionary type instead of NSDictionary, so change your controller with below one to get your desired output.
class ViewController: UIViewController, MCBrowserViewControllerDelegate {
#IBOutlet weak var input: UITextField!
#IBOutlet weak var output: UILabel!
var currentPlayer:String!
var appDelegate:AppDelegate!
override func viewDidLoad() {
super.viewDidLoad()
appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.MPCHandler.setupPeerWithDisplayName(UIDevice.current.name)
appDelegate.MPCHandler.setupSession()
appDelegate.MPCHandler.advertiseSelf(true)
NotificationCenter.default.addObserver(self, selector: #selector(peerChangedStateWithNotification(_:)), name: NSNotification.Name(rawValue: "MPC_DidChangeStateNotification"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleReceivedDataWithNotification(_:)), name: NSNotification.Name(rawValue: "MPC_DidReceiveDataNotification"), object: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func connect(_ sender: Any) {
if appDelegate.MPCHandler.session != nil{
appDelegate.MPCHandler.setupBrowser()
appDelegate.MPCHandler.browser.delegate = self
self.present(appDelegate.MPCHandler.browser, animated: true, completion: nil)
}
}
#IBAction func action(_ sender: Any) {
output.text = input.text
UserDefaults.standard.set(input.text, forKey: "MyName")
input.text = ""
}
func peerChangedStateWithNotification(_ notification: Notification) {
let userInfo = notification.userInfo!
let state = userInfo["state"] as! Int
if state != MCSessionState.connecting.rawValue{
self.navigationItem.title = "Connected"
}
}
func handleReceivedDataWithNotification(_ notification: Notification) {
let userInfo = notification.userInfo!
print(userInfo)
}
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
appDelegate.MPCHandler.browser.dismiss(animated: true, completion: nil)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
appDelegate.MPCHandler.browser.dismiss(animated: true, completion: nil)
}
override func viewDidAppear(_ animated: Bool) {
if let x = UserDefaults.standard.string(forKey: "myName") {
output.text = x
}
else {
output.text = "Default Name" //Set here default Name
}
self.createAlert(title: "HI", message: "ARE YOU READY")
}
func createAlert (title: String, message:String)
{
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: output.text, style: UIAlertActionStyle.default, handler: { (action) in
}))
self.present(alert,animated: true, completion:nil)
}
}
import UIKit
import MultipeerConnectivity
class ViewController: UIViewController, MCBrowserViewControllerDelegate {
#IBOutlet weak var input: UITextField!
#IBOutlet weak var output: UILabel!
#IBAction func dick(_ sender: Any) {
output.text = input.text
UserDefaults.standard.set(input.text, forKey: "MyName")
input.text = ""
}
var currentPlayer:String!
var appDelegate:AppDelegate!
override func viewDidLoad() {
super.viewDidLoad()
appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.MPCHandler.setupPeerWithDisplayName(UIDevice.current.name)
appDelegate.MPCHandler.setupSession()
appDelegate.MPCHandler.advertiseSelf(true)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.peerChangedStateWithNotification(_:)), name: NSNotification.Name(rawValue: "MPC_DidChangeStateNotification"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.handleReceivedDataWithNotification(_:)), name: NSNotification.Name(rawValue: "MPC_DidReceiveDataNotification"), object: nil)
}
#IBAction func connect(_ sender: Any) {
if appDelegate.MPCHandler.session != nil{
appDelegate.MPCHandler.setupBrowser()
appDelegate.MPCHandler.browser.delegate = self
self.present(appDelegate.MPCHandler.browser, animated: true, completion: nil)
}
}
#IBAction func action(_ sender: Any) {
output.text = input.text
UserDefaults.standard.set(input.text, forKey: "MyName")
input.text = ""
}
func peerChangedStateWithNotification(_ notification: Notification) {
let userInfo = notification.userInfo!
let state = userInfo["state"] as! Int
if state != MCSessionState.connecting.rawValue{
self.navigationItem.title = "Connected"
}
}
func handleReceivedDataWithNotification(_ notification: Notification) {
let userInfo = notification.userInfo!
print(userInfo)
}
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
appDelegate.MPCHandler.browser.dismiss(animated: true, completion: nil)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
appDelegate.MPCHandler.browser.dismiss(animated: true, completion: nil)
}
*func viewdidloadOverride; func viewDidAppear*(_ animated: Bool) {
if let x = UserDefaults.standard.string(forKey: "myName") {
output.text = x
}
else {
output.text = "x" //Set here default Name
}
self.createAlert(title: "HI", message: "ARE YOU READY")
}
func createAlert (title: String, message:String)
{
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: output.text, style: UIAlertActionStyle.default, handler: { (action) in
}))
self.present(alert,animated: true, completion:nil)
}
}

Xcode 8 - swift 3: Creating an image format with an unknown type is an error

I get an error when selecting an image with UIImagePicker:
[Generic] Creating an image format with an unknown type is an error
I'm using Xcode 8.1 and Swift 3.
I've already searched all around the web but nothing seems to solve my problem, please help!
Here it's my code:
class TabBarController: UITabBarController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var isSelected: Bool = false
var imgPicker: UIImagePickerController = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
//imgPicker = UIImagePickerController()
imgPicker.delegate = self
imgPicker.allowsEditing = false
imgPicker.sourceType = .photoLibrary
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
imgPicker.dismiss(animated: true, completion: nil)
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.performSegue(withIdentifier: "toPostPicture", sender: image)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func askImagePickerSource(sender: UIViewController) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: { (action: UIAlertAction) in
self.imgPicker.sourceType = .camera
self.imgPicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .camera)!
sender.present(self.imgPicker, animated: true, completion: nil)
})
let photoLibraryAction = UIAlertAction(title: "Photo Library", style: .default, handler: { (action: UIAlertAction) in
self.imgPicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
sender.present(self.imgPicker, animated: true, completion: nil)
})
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (UIAlertAction) in
sender.dismiss(animated: true, completion: nil)
}
alert.addAction(cameraAction)
alert.addAction(photoLibraryAction)
alert.addAction(cancelAction)
sender.present(alert, animated: true, completion: nil)
} else {
self.imgPicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
sender.present(self.imgPicker, animated: true, completion: nil)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toPostPicture" {
if let postPictureVC = segue.destination as? PostPictureVC {
if let image = sender as? UIImage {
postPictureVC.image = image
}
}
}
}
}
I faced the same issue by not adding delegate as 'self' for the UIImagePickerController. After adding it I was able to get the selected image from gallery. But even after adding delegate as self and able to access the image (Display on an ImageView), I was still getting the same error. After a further research on SO I got to know that this is just a bug and doesn't affect the app in any way.
See also "Creating an image format with an unknown type is an error Objective-C Xcode 8"
Can you post the .debugDescription of the info parameter in your picker delegate?
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
print(info.debugDescription)
...
}