iOS share extension exception - items configuration - ios

I'm having troubles implementing the share extension in an application. I'm using swift 3, xcode8.
override func configurationItems() -> [Any]! {
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
let item = SLComposeSheetConfigurationItem();
item?.title = "Test";
item?.value = "Value";
item?.tapHandler = self.show;
return [item]
}
func show() {
print("TEST");
}
When I add that code to configure the items, I get the exception :
2016-09-19 09:22:20.623471 ARShareExtension[10583:675495] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue setChangeObserver:]: unrecognized selector sent to instance 0x17025af40'
I don't know what is wrong, I'm doing it as described in the apple developer site. I would appreciate if someone could help me :) thanks

A bit late, but if anyone still has problems with this, SLComposeSheetConfigurationItem() is now returning an Optional for some reason, but the return value is supposed to be an array of non-optional items, so you can do either
let item = SLComposeSheetConfigurationItem()!
or
guard let item = SLComposeSheetConfigurationItem() else { return nil }

Related

How to handle NSException error

So, I've been making a basic calculator. But I've run into an issue.
My code.
#IBAction func calculate(_ sender: UIButton) {
let stringExpression = resultLabel.text!
let expression = NSExpression(format: stringExpression)
let result = expression.expressionValue(with: nil, context: nil) as! NSNumber
resultLabel.text! = String(result.doubleValue) // Writes response on textLabel :D
}
The code above works. However, when a input such as 5++6 is entered it crashes my app. I'm not very sure how to deal with this.
The following error is shown when a invalid input is entered.
The error given.
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I'm not sure how I could make it display "Error".
And this should work for any type of error.
You have to pass a valid expression to the NSExpression initialiser or else it will throw an exception. There is no Swift-only way to catch exceptions so the only possibility for you is to make sure only valid input can be generated.

iOS 11 NSPredicate search on Swift array crashing - NSUnknownKeyException

I am using NSPredicate to filter an array in Swift. The problem is after updating to iOS 11 (Xcode 9 /w Swift 4), I keep getting a crash on the filter line. Here is the crash log:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: >'[ valueForUndefinedKey:]: this class is not key >value coding-compliant for the key name.'
Here is an example of the class that I have an array of:
final class Model: NSObject {
let name: String
init(name: String) {
self.name = name
}
}
Here is the code that is crashing:
let myArray = [Model(name: "Jason"), Model(name: "Brian")]
let predicate = NSPredicate(format: "name == 'Jason'")
let filteredArray = myArray.filter { predicate.evaluate(with: $0)}
Question is why is this crashing now that I updated to iOS 11?
After fighting with this for a while, I finally came across the answer!
A subtlety of updating to Swift 4 is that classes that are subclasses of NSObject are no longer implicitly exposed to objective-c like they were before. Because of this, you need to explicitly annotate classes/functions with #objc. The compiler will notify you of places where the annotation is needed, but not in this case.
Ultimately because of this, the key-value lookup was no longer implicitly exposed to objective-c, which is needed to filter with NSPredicate. The code below fixes the crash!
Solution 1
extension Model {
#objc override func value(forKey key: String) -> Any? {
switch key {
case "name":
return name
default:
return nil
}
}
}
Solution 2
Alternative thanks to Uros19: Instead of implementing the above function, you could annotate the property directly with #objc (e.g., #objc let name: String). You lose a little bit of clarity as to why you are annotating the property with #objc, but this is only a small consideration.
I hope this saves some people time and frustration :)

"This class is not key value coding-compliant for the key" error in Swift

I have been getting this error message in Swift:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Faceit.ViewController 0x7f8f72501e40> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key faceview.'
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var faceView: FaceView! {
didSet{
updateUI()
}
}
var expression = FacialExpression(eyes: .closed, mouth: .frown) {
didSet {
updateUI()
}
}
private func updateUI() {
switch expression.eyes {
case .open:
faceView?.eyesOpen = true
case .closed:
faceView?.eyesOpen = false
case .squinting:
faceView?.eyesOpen = false
}
faceView?.mouthCurvature = mouthCurvatures[expression.mouth] ?? 0.0
}
private let mouthCurvatures = [FacialExpression.Mouth.grin:0.5,.frown: -1.0,.smile:1.0,.neutral:0.0,.smirk:-0.5]
}
See: Thread 1: signal SIGABRT Xcode 6.1
You have to go into Interface Builder and look for the one (or more) outlets that have a warning triangle (follow the link for a screenshot). Once you delete those bad connections, you're either (1) ready to go because you have already connected your new objects or (2) you need to make the new connections so that you have all the elements loaded properly and you have no warning triangles.
Open your storyboard > Select the ViewController which class is showing error> Just remove all of the outlet> And reassign outlet.
Hope your problem will be fixed. This is not a big issue , by mistake you have multiple key or different name key for one outlet and specially its faceview.
#vadian has told me how to fix the issue. It worked, changed to faceview, also reconnect with Interface Builder. (This is important)!

Project presents instance which is not included in the app

I'm currently working on an app where you can set pins on a map and retrieve Flickr images associated with the app.
For some reason there's following error thrown:
-[Photo copyWithZone:]: unrecognized selector sent to instance
The strange thing is that there is nothing called "copyWithZone" in my project and I have no idea how it came here. How can I find the part of the project where there is an error?
The Photo class I created only inherits from NSManagedObject and the error is thrown in the following function on the fourth line in the for-loop:
func isDownloading() -> Bool {
var result = false
for next in self.photos {
if let downloadWorker = PendingPhotoDownloads.sharedInstance().downloadInProgress[next.description.hashValue] as? PhotoDownloadWorker {
if downloadWorker.isDownloading() {
result = true
break
}
}
}
return result
}
Thank you in advance.

Crashing on presenting IDMPhotoBrowser in Swift

I am integrating IDMPhotoBrowser in my Swift Project.
I have created a bridging header and I have imported IDMPhotoBrowser.
#import <IDMPhotoBrowser.h>
In my view controller:
class ViewController: UIViewController, IDMPhotoBrowserDelegate {
override func viewDidLoad() {
super.viewDidLoad()
var photoBro = IDMPhotoBrowser(photos: imagesArray)
photoBro.delegate = self
presentViewController(photoBro, animated: false, completion: nil)
}
But when it is executed, I get the following error
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString unloadUnderlyingImage]: unrecognized selector sent to instance 0x165d6870'
In IDMPhotoBrowser Library, I found this function in IDMPhoto.m
// Release if we can get it again from path or url
- (void)unloadUnderlyingImage {
_loadingInProgress = NO;
if (self.underlyingImage && (_photoPath || _photoURL)) {
self.underlyingImage = nil;
}
}
From the error it looks like it is expecting to do something to an array of IDMPhotos but instead has an array of strings...are you passing the right kind of array to the constructor?
As #GoatInTHeMachine pointed, I was not passing the right kind of array.
But as I wanted to pass the imageURLs, I had to change the constructor.
The following worked for me:
var photoBro = IDMPhotoBrowser(photoURLs: imagesArray)

Resources