Unrecognised Selector when using nicklockwood's CountryPicker in Swift - ios

I know they say there is no such thing as a stupid question, but I feel stupid since I know this question has been asked dozens of times before, but I can't seem to find one of the solutions which fit my case (I have made the effort of looking).
So the problem I face is that I am creating a Swift iOS project, and am looking to implement a country picker. From what i can tell, there is no native solution for that array of countries, so I came across what looks to be a nice custom solution by 'NickLockWood' ( https://github.com/nicklockwood/CountryPicker )
And the problem is that I am having a little trouble trying to get it to work in my Swift project, since all the sample and demo code provided is in obj-c (I am in the process of getting better at converting such code from one language to another, but I appear to not be at the ninja level yet for this..).
From what I can tell, this is how he uses it in his viewController
- (void)countryPicker:(__unused CountryPicker *)picker didSelectCountryWithName:(NSString *)name code:(NSString *)code
{
self.nameLabel.text = name;
self.codeLabel.text = code;
}
I have managed to try convert that into my Swift viewController as such..
func countryPicker(picker: CountryPicker?, didSelectCountryWithName name: String!, code: String!) {
println("\(name)")
println("\(code)")
}
So when the app launches, the listPicker is populated with country names and the associated flags. So I have a good feeling it is hooked up mostly correctly.
The error occurs when I spin the picker and it lands on a selection. I then get this...
exception 'NSInvalidArgumentException', reason: '-[UIViewController countryPicker:didSelectCountryWithName:code:]: unrecognized selector sent to instance 0x17dca740'
In my ViewController, where this picker is associated with, I used the storyboard to link the 'CountryPicker' delegate to the ViewController.
Then in the ViewController this is my code..
import UIKit
class RegionViewController: UIViewController, CountryPickerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
func countryPicker(picker: CountryPicker!, didSelectCountryWithName name: String!, code: String!) {
println("\(name)")
println("\(code)")
}
Am I perhaps missing something else here?
Thanks!

My error.
I hadnt associated the viewController I was working on in the storyboard to use the custom RegionViewController I was trying to reach.
Fixed that connection and all was right again.
Thanks!

Related

MessageKit set up MessageLabelDelegate for didSelectURL

I'm trying to open url from messages embedded in an NSAttributedString. I'm using the latest version of MessageKit. I'm using the function didSelectURL, but it doesn't seem to reach that part of the code. I came across this solution, but I wanted to follow up with regards to how to set up MessageLabelDelegate. Just like in the linked solution, I have implemented the delegate methods detectorAttributes and enabledDetectors.
I currently have MessageLabelDelegate set up as an extension to my ViewController, but it never seems to reach those methods.
extension ChatViewController:MessageLabelDelegate {
func didSelectURL(_url: URL) {
// .. open URL
}
}
It seems to be getting overwritten by the method didTapMessage in the MessageCellDelegate extension. I tried going through the example code in the MessageKit repo, but still unclear as to how it's meant to be set up or what I'm doing wrong.
UPDATE: The problem was the way I was declaring the NSAttributedString. I was setting its value as a string instead of a URL.
The MessageCellDelegate implements the the MessageLabelDelegate so you need to make sure that the messagesCollectionView.messageCellDelegate is set to the ChatViewController and that the ChatViewController has an extension for MessageCellDelegate where you can put your didSelectURL
public protocol MessageCellDelegate: MessageLabelDelegate {

Implementing Methods from Objective C Library with Swift

I am trying to implement the following method in swift:
From the class FLIROneSDKImageReceiverDelegate, which is subclassed inside my ViewController class as so:
class ViewController: UIViewController, FLIROneSDKImageReceiverDelegate,
FLIROneSDKStreamManagerDelegate,
FLIROneSDKImageEditorDelegate{
Note that I have already created a bridging header etc.
In the FLIROneSDKImageReceiverDelegate header file:
- (void) FLIROneSDKDelegateManager:(FLIROneSDKDelegateManager *)delegateManager didReceiveBlendedMSXRGBA8888Image:(NSData *)msxImage imageSize:(CGSize)size;
Am I wrong in thinking that this is the correct way to implement this function?
func FLIROneSDKDelegateManagerdidReceiveBlendedMSXRGBA8888ImageimageSize(delegateManager: FLIROneSDKDelegateManager!, msxImage: NSData, size: CGSize){
Note that FLIROneSDKDelegateManager is a class.
Off the top of my head, but try this:
func FLIROneSDKDelegateManager(delegateManager: FLIROneSDKDelegateManager!, didReceiveBlendedMSXRGBA8888Image msxImage: NSData!, imageSize size: CGSize) {
// method imp
}
#Laxsnor's solution in the comments on the answer by #aaron-wojnowski helped me too, thanks both.
To consolidate:
The problem is a conflict created by the name FLIROneSDKDelegateManager being used as a both a class name and a function name - which seems to be OK in Objective-C but not in Swift.
Replacing the class FLIROneSDKDelegateManager with NSObject in the function parameter seems to solve the problem without side-effects. This has to be done in both the Objective-C protocol header file and the Swift delegate class source file.
NOTE I also found this same solution applied more broadly to Swift-ify the entire FLIROneSDK at https://github.com/jruhym/flirmebaby.
Happy developing for FLIROne on Swift. (I'm new to FLIROne and relatively new to Swift so apologies if my language isn't quite precise enough.)

Compile and runtime failures when importing interfaces with category extensions in XCode 7

I'm trying to get an example of running OpenEars with the RapidEars plugin running in Swift 2.2 (XCode 7.3.1). However, I suspect I'm having a larger issue with using Objective-C interfaces with extensions in a Swift project (or my understanding of how that works).
The OpenEars code is Obj-C. However I was able to get it running in my swift project through the standard Obj-C -> Swift translation techniques.
Abbreviated code follows. The full example is on a forked Github and updated to Swift-2.2: https://github.com/SuperTango/OpenEars-with-Swift-
This following example is working great. You can see the entire project by checkng out the "working-opears-swift2.2" tag.
OpenEarsTest-Bridging-Header.h:
#import <OpenEars/OELanguageModelGenerator.h>
#import <OpenEars/OEAcousticModel.h>
#import <OpenEars/OEPocketsphinxController.h>
#import <OpenEars/OEAcousticModel.h>
#import <OpenEars/OEEventsObserver.h>
ViewController.swift:
class ViewController: UIViewController, OEEventsObserverDelegate {
var openEarsEventsObserver = OEEventsObserver()
override func viewDidLoad() {
super.viewDidLoad()
loadOpenEars()
}
func loadOpenEars() {
self.openEarsEventsObserver = OEEventsObserver()
self.openEarsEventsObserver.delegate = self
var lmGenerator: OELanguageModelGenerator = OELanguageModelGenerator()
addWords()
var name = "LanguageModelFileStarSaver"
lmGenerator.generateLanguageModelFromArray(words, withFilesNamed: name, forAcousticModelAtPath: OEAcousticModel.pathToModel("AcousticModelEnglish"))
lmPath = lmGenerator.pathToSuccessfullyGeneratedLanguageModelWithRequestedName(name)
dicPath = lmGenerator.pathToSuccessfullyGeneratedDictionaryWithRequestedName(name)
}
func startListening() {
do {
try OEPocketsphinxController.sharedInstance().setActive(true)
OEPocketsphinxController.sharedInstance().startListeningWithLanguageModelAtPath(lmPath, dictionaryAtPath: dicPath, acousticModelAtPath: OEAcousticModel.pathToModel("AcousticModelEnglish"), languageModelIsJSGF: false)
} catch {
NSLog("Error!")
}
}
// A whole bunch more OEEventsObserverDelegate methods that are all working fine...
func pocketsphinxDidStartListening() {
print("Pocketsphinx is now listening.")
statusTextView.text = "Pocketsphinx is now listening."
}
Up until this point, everything is working great.
However, In order to use the "RapidEars" plugin, the documentation (http://www.politepix.com/rapidears/) says to:
Add the framework to the project and ensure it's being included properly.
import two new files (that are both "categories" to existing OpenEars classes):
#import <RapidEarsDemo/OEEventsObserver+RapidEars.h>
#import <RapidEarsDemo/OEPocketsphinxController+RapidEars.h>
Change methods that used: startListeningWithLanguageModelAtPath to use startRealtimeListeningWithLanguageModelAtPath
add two new OEEventsObservableDelegate methods.
func rapidEarsDidReceiveLiveSpeechHypothesis(hypothesis: String!, recognitionScore: String!)
func rapidEarsDidReceiveFinishedSpeechHypothesis(hypothesis: String!, recognitionScore: String!)
The new code can be found by checking out the rapidears-notworking-stackoverflow tag from the above github repo
Problem 1:
When doing completion in the XCode editor, the editor sees WILL perform autocompletion on the startRealtimeListeningWithLanguageModelAtPath method, however when the code is run, it always fails with the error:
[OEPocketsphinxController startRealtimeListeningWithLanguageModelAtPath:dictionaryAtPath:acousticModelAtPath:]: unrecognized selector sent to instance 0x7fa27a7310e0
Problem 2:
When doing auto completion in the XCode editor, it doesn't see the two new delegate methods defined in RapidEarsDemo/OEPocketsphinxController+RapidEars.h.
I have a feeling that these are related, and also related to the fact that they failing methods are defined as Categories to Objective-C classes. But that's only a guess at this point.
I've made sure that the RapidEars framework is imported and in the framework search path.
Can anyone tell me why this is happening? Or if there's some Swift magic incantation that I missed?
The problem could be the one described in the link below, where category methods in a static library produce selector not recognized runtime errors.
Technical Q&A QA1490: Building Objective-C static libraries with categories

PureLayout on device: unrecognized selector sent to instance

today I found out that there is an issue with my project. I can't run it on a real device, because I am getting an 'unrecognized selector sent to instance' error when it reaches the part of code that comes from a pod that I am using. I can run the app if I comment the part with this code.
The problem here is that I did not encounter this problem before and it just came out of nothing.
Under linked frameworks and libraries, my pod is linked as 'optional', because I get 'dyld: Library not loaded' error if it is marked as 'required'. Bitcode is enabled as well, changing this didn't make any difference.
Currently I am using XCode 7.0 (7A220) and Cocoapods version 0.38.2.
I'd be glad for any given tips on this.
#Edit
I've found out, that I was able to run other pods. The issue comes with PureLayout pod.
#Edit2 Code
class MainViewController: UIViewController {
var label : UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.setupView()
}
func setupView() {
self.view.backgroundColor = UIColor.whiteColor()
label = UILabel()
self.view.addSubview(label)
label.autoPinEdgesToSuperviewEdges()
}
}
This view controller is displayed when app is launching. This code represents the whole situation as app crashes even on this simple view -
[UILabel autoPinEdgesToSuperviewEdges]: unrecognized selector sent to instance.
Edit
Same code works on release build config. Does anyone know why?
The best thing I can suggest is start all over from the vary beginning. Depending on how much code you have this might be intimidating, but it is the best I have to offer. But my advice is this: don't move onto something else until the bug is obliterated, doing so can save you a lot of stress.

Subclassing Parse's PFUser in Swift

First off, I know similar questions have been asked before and I've tried following the advice of this stackoverflow answer here to no avail. I also tried adding the basic gist of this as a comment, but I don't have enough rep yet :( Basically I am trying to use PFSubclassing to extend Parse's PFUser model. As such, here's my corresponding code:
User.swift:
import Foundation
import CoreLocation
class User : PFUser, PFSubclassing {
override init() {
super.init()
}
convenience init(email: String!) {
self.init()
self.email = email
self.username = email
}
// don't need to call User.registerSubclass() in AppDelegate because this
// is handling that here
override class func load() {
self.registerSubclass()
}
// Commented out because this is extending PFUser
// override class func parseClassName() -> String! {
// return "PFUser"
// }
}
Result on Tests:
-[PFObject _loadSensitiveUserDataFromKeychainItemWithName:]: unrecognized selector sent to instance 0x7f98ebc1c250
I'm also doing the following in my Bridging-Header:
#import <Parse/Parse.h>
#import <Parse/PFObject+Subclass.h>
If I un-comment "parseClassname() in User.swift" I get:
failed: caught "NSInvalidArgumentException", "Cannot initialize a PFUser with a custom class name."
Which leads me to believe that setting up the interfaces is at least partially working.
Based on all of the advice I've seen, I can't seem to figure out what I'm doing wrong. There is also an open bug that produces the same error message, but it is caused by using Parse's local data store and I haven't configured any of that.
At this point I feel like I am missing something dead obvious, or I am being affected by the same bug as mentioned above. Any suggestions?
Okay, solved my own problem here through trial and error. Essentially it looks like a cached logged in PFUser was causing problems. When Parse would initially load it was loading the logged in state from the emulator which was conflicting with the newly registered User subclass.
To fix this you can either:
Restart the emulator.
Call PFUser.logOut() right after Parse.setApplicationId() in AppDelegate to flush the cached user.
Hopefully this helps someone else out in the future!
I solved this issue by changing the initial view controller. It didn't register the user because it didn't go through the view controller that previously stated/identified who the user was.
What I did specifically:
Set the initial view controller, for the controller that captures who the user is and then segue your way past to where you want to be.
Restart the simulator.

Resources