I reinstalled Xcode 6 after not being able to get the usual ctrl-click help.
Now, whenever I create a new Xcode project for OS X Cocoa Application, the main.swift file is no longer in the supporting files as it used to be. I have 2 partitions and Mavericks on one, Yosemite on the other.
Can anybody please tell me what is going on and how to get around it?
This is my first question, be free to point me out any mistakes in it as well, please.
Thanks
You don't necessarily need a main.swift file. The main (heh) purpose of that file is to call NSApplicationMain(), the function that gets a Cocoa app up and running. But, since every app needs to do that, Apple added a less-boilerplate way of doing things.
Now, you just need to label your app delegate class with the #NSApplicationMain attribute. Then Xcode will build in the right hooks to get your app launched into its main run loop with an instance of your chosen class as NSApp's delegate. The new project templates do this, which is why you don't need a main.swift anymore. (It also frees you from needing to designate the app delegate in a main nib, which is useful for apps using OS X storyboards.)
Of course, if you want to customize your app setup a bit more—say, by running some code before the run loop kicks off, or with a custom NSApplication subclass—you can still create a main.swift file and call NSApplicationMain() yourself. (If you do, be sure to also remove the #NSApplicationMain attribute from your app delegate class.)
Related
I've designed an app that includes support for the touch bar. The touch bar is created in Interface Builder. All code uses Swift's #available checks to make sure that no touch bar code gets executed on macOS prior to 10.12.
The XIB (and app) is set to deploy to 10.10, but when I run my app I still get errors like:
-[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (NSTouchBar)
How can I make sure that decoding the XIB skips the touch bar on macOS prior to 10.12?
You have two choices.
Create the UI programmatically.
Register dummy class pairs for the class name. I'm not sure how to achieve this in Swift, but there is an Obj-C solution here: How to use NSVisualEffectView backwards-compatible with OSX < 10.10?. That answer also provides some extra caution regarding subsequent access of the component.
I have not been able to get my NSPopover to detach to a window in my own projects, so to simplify I tried the Apple sample.
I downloaded a fresh copy of the Apple sample project: http://developer.apple.com/library/mac/samplecode/Popover/Introduction/Intro.html
It behaves the same, which is to say I can't drag the window to detach it either.
The project seems to provide all the correct windows and controllers and implements the detachableWindowForPopover: delegate method. However the method is never called.
Does anyone know the secret to detachable NSPopovers?
Found the answer while typing the question…
Mac OS X 10.10 Yosemite has a new delegate method:
(BOOL)popoverShouldDetach:(NSPopover *)popover
The default behavior on Yosemite is NO (should not detach). So delegates must implement this method in order for windows to be detachable. The sample project does not implement this method, so when compiled on Yosemite it will not detach (and also produces several deprecation warnings -- maybe I should have taken that hint that it needs an update).
Adding:
- (BOOL)popoverShouldDetach:(NSPopover *)popover {
return YES;
}
To MyWindowController.m fixes the problem.
I have been searching a lot in the inter webs and Stackoverflow. Unfortunately there doesn't seem to be much info around the new Xcode version, iOS 8 specifically with Swift and working without the Interface Builder.
The Templates to choose from as a starting point now does not have the option to start with an empty application. The least setup you have is to take the single view application, which already gives you the ViewController and a basic Storyboard.
I hate storyboards and I hate nibs. I want to do everything in code. I tried to delete the storyboard file, instantiate the window, set the rootViewController and make it visible just like in the good old days. the ViewController initializes without nib and bundle.
The result is this a SIGABRT with this error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Main' in bundle NSBundle </Users/[username]/Library/Developer/CoreSimulator/Devices/BC38B690-D30E-44FB-93B1-AB861D03B414/data/Containers/Bundle/Application/B6C160C8-67E1-4A74-9F81-55D097262050/blabla.app> (loaded)'
I sure hope that I will still be able to do UI without Interface Builder. Anyone has an idea on how to progress? I remember I was able to use an empty application with the previous Beta versions of Xcode 6.
In my opinion storyBoards are awesome. They make the development cycle easy and quick. But if you do not want them you can create a Single View Application template.
Delete the storyBoard and Follow these steps
1) Go to Your Target
2) Deployment Info
3) Main Interface -> Delete Main and keep field empty
It will not load a storyboard or any view. Now it's your responsibility to load Window and create rootViewControllers and views programmatically
The method outlined by codester is a good solution, but (in Xcode 6.0.1) the final step - deleting "Main" from the Main Interface section - would not work for me; I would delete the string, but as soon as I navigated away from that page or tried to run the app, the field would be repopulated with "Main". I ended up having to manually delete the "UIMainStoryboardFile" key/value entry in the applications Info.plist.
I am just starting out learning to build interfaces, but the book I am following is a little dated and it says that Xcode should create it for me with my new project, however it didn't. So now I need to link my buttons to my app delegate, but I can't because it isn't showing up when I right click on my buttons. And yes, I did define my methods and instance variables.
Xcode very much will create a MainWindow.xib if you choose Cocoa Application as the project type. Check to make sure you aren't either creating an iOS project or a command-line tool... both can be easy to accidentally select when you are just starting to learn.
(FYI, I just verified in Xcode 4.2.1 that a MainWindow.xib was created for me.)
I create a window in a helper tool that runs in the background (it's not an app bundle with a .nib and Info.plist, but a plain executable). When -makeKeyAndOrderFront: is called, the window is displayed but it does not "pop" out like an active window.
Can this be fixed?
Regards,
Erik
You should wrap the helper tool as a regular .app bundle with at least Info.plist. Then the problem goes away. A GUI app in OS X needs to have an Info.plist to receive events correctly.
The way a GUI app misbehaved if not in an app bundle has never been clear to me. If I remember correctly, it changed over time, depending on OS X's versions. I think it behaved worse in previous versions of OS X. For example, the window is shown but I couldn't click any UI inside it.
Many people who compiled a program in a cross-platform toolkit faced this problem, see e.g. this discussion here in the WxWidgets wiki. Apparently, OS X doesn't mark a program not within an .app bundle as a foreground-able app, which causes your problem. You can use TransformProcessType from your binary not inside an .app bundle to make a foreground-able app to solve your problem, but that's not a documented/intended usage of this function.
So, just wrap it in an .app bundle.
Update:
This "foreground-able-ness" is controlled by the activationPolicy of an app, see this doc on NSApplication. Found the info on this post on Cocoa with love.