Subclassing Parse's PFUser in Swift - ios

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.

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 {

Opening Realm hangs after implementing new object class

I wish to support rearranging a UITableView. I have seen other answers here, here, and here recommend using a another class to manage the realm objects. The only problem is as soon as I add the class I cannot successfully open a Realm.
import RealmSwift
class Data: Object {
dynamic var id = ""
}
// Adding this class causes issues
class DataList: Object {
let list dataList = List<Data>()
}
Any ideas on what is going wrong here? When I attempt to open the Realm it just hangs: no error thrown.
Edit:
From the realm doc it says they should be declared as let.
Thanks to Tj3n for the solution. Migrate your schema or reinstall the app fixes the issue. Here is some doc on that.

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

'Use of Unresolved Identifier' in Swift

So I have been making an app, and everything has been working great. But today I made a new class like usual and for some reason in this class I can't access Public/Global variable from other classes. All the other classes can, but now when ever I try to make a new class I can't. How would this be fixed?
I am using Swift and Xcode 6.
Working Class:
import UIKit
import Foundation
import Parse
import CoreData
var signedIn = true
class ViewController: UIViewController {
New Class:
import UIKit
class NewClass: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
signedIn = false
}
But on signedIn = false
I get the error:
use of unresolved identifier "signedIn"
One possible issue is that your new class has a different Target or different Targets from the other one.
For example, it might have a testing target while the other one doesn't. For this specific case, you have to include all of your classes in the testing target or none of them.
Once I had this problem after renaming a file. I renamed the file from within Xcode, but afterwards Xcode couldn't find the function in the file. Even a clean rebuild didn't fix the problem, but closing and then re-opening the project got the build to work.
'Use of Unresolved Identifier' in Swift my also happen when you forgot to import a library. For example I have the error:
In which I forgot the UIKit
import UIKit
Sometimes the compiler gets confused about the syntax in your class. This happens a lot if you paste in source from somewhere else.
Try reducing the "unresolved" source file down to the bare minimum, cleaning and building. Once it builds successfully add all the complexity back to your class.
This has made it go away for me when re-starting Xcode did not work.
Another place I've seen this error is when your project has multiple targets AND multiple bridging headers. If it's a shared class, make sure you add the resource to all bridging headers.
A good tip to is to look in the left Issue Navigator panel; the root object will show the target that is issuing the complaint.
For me this error happened because I was trying to call a nested function. Only thing I had to do to have it fixed was to bring the function out to a scope where it was visible.
In my case, I had an Object-C file which was also in the same Target Membership. I fixed by adding #import "YourObjectCFileHeader.h" inside file Bridging-Header.h
Because you haven't declared it. If you want to use a variable of another class you must use
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var DestViewController : ViewController = segue.destinationViewController as ViewController
DestViewController.signedIn = false
}
You have to put this code at the end of the NewClass code
Your NewClass inherits from UIViewController. You declared signedIn in ViewController. If you want NewClass to be able to identify that variable it will have to be declared in a class that your NewClass inherits from.
I got this error for Mantle Framework in my Objective-Swift Project.
What i tried is ,
Check if import is there in Bridging-Header.h file
Change the Target Membership for Framework in Mantle.h file as shown in below screenshot.
Toggle between Private Membership first build the project , end up with errors.
Then build the project with Public Membership for all the frameworks appeared for Mantle.h file, you must get success.
It is just a bug of building with multiple framework in Objective-C Swift project.
If this is regarding a class you created, be sure that the class is not nested.
F.e
A.swift
class A {
class ARelated {
}
}
calling var b = ARelated() will give 'Use of unresolved identifier: ARelated'.
You can either:
1) separate the classes if wanted on the same file:
A.swift
class A {
}
class ARelated {
}
2) Maintain your same structure and use the enclosing class to get to the subclass:
var b = A.ARelated
I did a stupid mistake. I forgot to mention the class as public or open while updating code in cocoapod workspace.
Please do check whether accesor if working in separate workspace.
You forgot to declare the variable. Just put var in front of signedIn = false
My issue was calling my program with the same name as one of its cocoapods. It caused a conflict. Solution: Create a program different name.
This is not directly to your code sample, but in general about the error. I'm writing it here, because Google directs this error to this question, so it may be useful for the other devs.
Another use case when you can receive such error is when you're adding a selector to method in another class, eg:
private class MockTextFieldTarget {
private(set) var didCallDoneAction = false
#objc func doneActionHandler() {
didCallDoneAction = true
}
}
And then in another class:
final class UITextFieldTests: XCTestCase {
func testDummyCode() {
let mockTarget = MockTextFieldTarget()
UIBarButtonItem(barButtonSystemItem: .cancel, target: mockTarget, action: MockTextFieldTarget.doneActionHandler)
// ... do something ...
}
}
If in the last line you'd simply call #selector(cancelActionHandler) instead of #selector(MockTextFieldTarget.cancelActionHandler), you'd get
use of unresolved identifier
error.

Unrecognised Selector when using nicklockwood's CountryPicker in Swift

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!

Resources