(NSMenuItem): missing setter or instance variable - macos

I am encountering a strange error:
2015-04-02 12:20:14.642 test[21167:257788] Failed to connect
(testApp) outlet from (test.AppDelegate) to (NSMenuItem): missing
setter or instance variable
inserted id: 122
I occured when a added a menuItem to a menu and connected a function to it.
I do not know what the Problem is. The app works fine but i don't think it is a smart idea to ignore the error.
What is meant by setter or instance variable? Why is it needed?
UPDATE: Here is the relevant code:
import Cocoa
import Foundation
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var statusMenu: NSMenu!
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
func applicationDidFinishLaunching(aNotification: NSNotification) {
let icon = NSImage(named: "statusIcon")
statusItem.image = icon
statusItem.menu = statusMenu
// Time for constant repeat
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "timerRepeat", userInfo: nil, repeats: true)
}
// Method to call the tracking core
func timerRepeat() {
//....
}
#IBAction func frontEnd(sender: NSMenuItem) {
var targetURL : String = NSBundle.mainBundle().resourcePath!
targetURL = targetURL + "/" + "front.app"
let workspace = NSWorkspace()
workspace.launchApplication(targetURL)
}
#IBAction func menuClicked(sender: NSMenuItem) {
NSApplication.sharedApplication().terminate(self)
}
}

You have a broken outlet in your xib file. Usually it happens when you set up an outlet to ivar or property which is later deleted or renamed not using Xcode's rename feature.

Also make sure that your custom view or view controller class is added to your target. (Project => Target Name => Build Phases => Compile Sources). It's possible that a file is in your project but not your target.

This happens because you at one point created an #IBOutlet for a storyboard element. You then later removed the code (reference) from your swift file.
I created an example where I create two extra #IBOutlets (I named them 'correctField' and 'incorrectField'- both are incorrect though) and connected them from my storyboard to my swift file.
I then removed the code from my swift file. This generates the log as shown in the following figure :
To remove this kind of log message, you can do the following:
Go to the 'storyboard' and select the storyboard elements you created connections (#IBOutlets) from.
Open the 'connection inspector' as showed in the figure below
Remove the Referencing Outlets which are incorrect (in my case it is the 'correctField' and 'incorrectField')
Done
This was done in xCode 11

Related

Mapping a Topbar Menu Item in SwiftUI app to opening a specific bundled PDF?

SwiftUI, macOS:
I'm trying to get a menu item to open "default PDF viewer of your choice", with a specific bundled PDF.
Here's what I have thus far:
import SwiftUI
import WebKit
import PDFKit
func Guide1(_ sender: Any) {
if let pdfURL = Bundle.main.url(forResource: "Guide1", withExtension: "pdf"){
if NSWorkspace.shared.open(pdfURL) {
}
}
}
func Guide2(_sender: Any) {
if let pdfURL = Bundle.main.url(forResource: "Guide2", withExtension: "pdf"){
if NSWorkspace.shared.open(pdfURL) {
}
}
}
Now, what I'm missing is how to call these functions.
From previous tutorials, I've found that one way of getting the menu items to "do something" is to ctrl-click and drag the Menu Item entry to First Responder, and then select functions from the list. However, these Guide1 + Guide2 functions are not displayed.
Other tutorials suggest using #IBAction - but the minute I type that into a SwiftUI app, an error tells me to get the #IBaction replaced with "nothing". So I cannot use those either.
So, are these even valid strings for opening a PDF - and if so, how do I connect a dropdown menu item so that these PDFs are opened?
It needs to be added not in SwiftUI view but, for example and simplest, in AppDelegate as below
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBAction func Guide1(_ sender: Any) {
if let pdfURL = Bundle.main.url(forResource: "Guide1", withExtension: "pdf"){
if NSWorkspace.shared.open(pdfURL) {
}
}
}
then in your Main.storyboard (or XIB) just CTRL-drag from menu item to FirstResponder and Guide1 action is there to bind (sometime build might be required before that, but as tested on Xcode 11.2 it just works).

PFLoginViewController´s Twitter, Facebook buttons not working when subclassing

When I subclass PFLoginViewController from Parse so that I can customise UI, both Twitter and Facebook buttons stop working as they used to if I were not subclassing.
This is the class I instantiate my subclass from:
class SettingsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate, MFMailComposeViewControllerDelegate
{
#IBOutlet weak var loadingIndicator: UIActivityIndicatorView!
#IBOutlet weak var tableView: UITableView!
// THIS DOES WORK (without subclassing)
//var loginVC: PFLogInViewController = PFLogInViewController()
var loginVC:LogInViewController {
get{
let livc = LogInViewController()
livc.delegate = self
let suvc = SignUpViewController()
suvc.delegate = self
livc.signUpController? = suvc
return livc
}}
And this is my subclass of PFLogInViewController
class LogInViewController: PFLogInViewController {
static let forgotPassword = "Trouble Signing In?"
override func viewDidLoad() {
super.viewDidLoad()
let lv = self.logInView
self.facebookPermissions = ["public_profile", "email"]
self.fields = [PFLogInFields.UsernameAndPassword, .Facebook, .Twitter, .SignUpButton, .LogInButton, .PasswordForgotten, .DismissButton]
lv?.logo = UIImageView(image: UIImage(named: "myImage"))
lv?.logo?.contentMode = UIViewContentMode.ScaleAspectFit
lv?.emailAsUsername = true
self.view.backgroundColor = UIColor.whiteColor()
}
It might be a bug in Parse´s side, though. Any help would be appreciated!
This is a known issue - it looks like this bug was patched in the GitHub repo (see this commit) but not in the Cocoapod, if that's what you're using. I'm hoping they'll push the changes over soon :)
The reason for the bug in the old code is that the superclass is not updating the target/actions for the buttons when you set which fields you want in viewDidLoad. PFLoginViewController configures the target/actions in its viewDidLoad, but since you're setting the self.fields after calling super.viewDidLoad (which is what you should be doing, since you always call super first :) ), the field target/actions aren't re-updated. In other words, it looks like, the way PFLogInViewController was written, it only works if the fields don't change after its viewDidLoad is called :/. And since the default fields don't include a Facebook button, the Facebook button will never be set up. A simple solution is just to move self.fields =... before super.viewDidLoad().

Xcode_OSX/Swift_NSPopUpButton.

I am incredibly new to this, so please keep that in mind!
I've been at this all night, watched countless videos/haunted
countless forums...I can't find one single answer!
I am trying to make a basic popup menu in Swift/OSX What I need to figure out is:
How can I add more than the 'three items' to this menu
Whatever is selected in the popup, for that info to send an integer
value to another number.
I very much would appreciate your help, Thanks.
A NSPopupButton is a container for a bunch of NSMenuItem objects so to add an item you can use
func addItemWithTitle(_ title: String!)
The NSMenuItem gets constructed for you by the call.
and as you may wish to start from scratch you can use
func removeAllItems()
To clean existing items from the button.
There are also other methods around moving and removing menu items from the button.
A NSPopupButton is-a NSControl so you can use var action: Selector to set the action sent when an item is selected and var target: AnyObject! to control which object receives the message. Or just wire it up in Interface Builder.
protocol FooViewDelegate{
func itemWithIndexWasSelected(value:Int)
}
class FooViewController: NSViewController {
#IBOutlet weak var myPopupButton: NSPopUpButton!
var delegate: FooViewDelegate?
let allTheThings = ["Mother", "Custard", "Axe", "Cactus"]
override func viewDidLoad() {
super.viewDidLoad()
buildMyButton()
}
func buildMyButton() {
myPopupButton.removeAllItems()
myPopupButton.addItemsWithTitles(allTheThings)
myPopupButton.target = self
myPopupButton.action = "myPopUpButtonWasSelected:"
}
#IBAction func myPopUpButtonWasSelected(sender:AnyObject) {
if let menuItem = sender as? NSMenuItem, mindex = find(allTheThings, menuItem.title) {
self.delegate?.itemWithIndexWasSelected(mindex)
}
}
}
All the button construction can be done in Interface Builder rather than code too. Remember that you can duplicate items with CMD-D or you can drag new NSMenuItem objects into the button.

Instance of class does not initialize IBOutlets in class

I have a class called AccountPanelController that contains two variables: an IBOutlet to an NSTableView, as well as a simple Int. When I run my app, awakeFromNib: prints that both the NSTableView and the Int have been initialized. From another file, I have created and initialized an instance of the class AcountPanelController. Via a button connected to that other file, I call openPanel: on the instance. At that point accountTable does not exist but somehow number does. In other words, when I initialize the instance of my class the Int is being created, but the NSTableView, an IBOutlet, is not. Why is this? I assume it is because accountTable is an IBOutlet, and therefore will not reinitialize. What can I do about this? (Xcode Version 6.1.1 (6A2008a), Cocoa, Swift)
Thanks,
bigelerow
class AccountPanelController: NSObject, NSTableViewDataSource {
#IBOutlet weak var accountTable: NSTableView!
var number: Int = 5
override func awakeFromNib() {
println(accountTable) // prints "<NSTableView: 0x100512aa0>"
println(number) // prints "5"
}
func openPanel() {
println(number) // prints "5"
println(accountTable) // prints "nil"
accountTable.reloadData() // throws error "unexpectedly found nil while unwrapping an Optional value"
}
// NSTableView data source functions below...
}
Other File
#IBAction func buttonPressed(sender: AnyObject?) {
var instance = AccountPanelController()
instance.openPanel()
}
IB automatically creates instances of all objects with IBOutlets when their xib file is loaded. So, instead of creating my own, second, instance in another file:
var instance = AccountPanelController()
I simply made a reference to the instance IB had already made for me:
IBOutlet weak var IBInstance: AcountPanelController!
Unlike the second instance, this IB created version contained initialized IBOutlets. When I referenced AccountTable it was not nil.

Swift NSViewController

I'm new to cococa and swift, and I'm tring to create a custom ViewController.
class StatusUpdate : NSViewController {
#IBOutlet var StatusView: NSView!
#IBOutlet var eventsFoundCell: NSTextFieldCell!
#IBAction func update(sender: AnyObject) {
StatusView.hidden = false
eventsFoundCell.stringValue = "A"
}
}
The code as shown above is working as you would expect it.
But what I tring to do is to add an other function to that class like :
func otherUpdate() {
eventsFoundCell.stringValue = "B"
}
In order to update the stringValue of the eventsFoundCell variable.
So I could call it in an other class :
var update = StatusUpdate()
update.otherUpadte()
When calling update.otherUpadte() with in n other class,
I'm always getting an error like :
Thread1: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP, subcode=0x0)
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
Any idea on show I could do this ?
Thank you !
It is because in this line
var update = StatusUpdate()
You are creating a new instance of StatusUpdate. The variable StatusView is not bound to any NSView
You already got the answer, so this is recommendation only. It will make your Cocoa life way easier if you follow well established conventions. So, instead of:
#IBOutlet var StatusView: NSView!
you should write
#IBOutlet var statusView: NSView!
There are many cases in Cocoa where proper capitalisation (and style in general) are assumed in order for the frameworks to work.

Resources