Nib file (and code) organization in a one-window, non-document-based app - nib

Good people of StackOverflow,
I am in the early stages of building a non-document-based Cocoa application. What I'm aiming for is a window layout similar to iTunes, with a left, middle, and right pane. The Xcode template for such an application includes a file called MainMenu.xib containing both the main menu, and the main application window, with supporting logic contained in the MyApp_AppDelegate class.
I can already foresee that continuing down this route will eventually lead to a very large and disorganized app delegate class. Therefore, my spidey sense tells me to break out the logic for the main window into its own NSWindowController subclass (and accompanying XIB file). Furthermore, would I be correct to split out each pane into its own NSViewController subclass? This would seem to better separate my concerns, at the expense of more files and some extra code to wire everything together.
The closest advice I've been able to find is in Apple's Interface Builder User Guide but it does not answer the question directly. However, I guess my question is not about nib files in particular, but about high-level application organization.

Related

What is the difference between an "app" project and a "framework" project in Xcode?

I am working on a project with SwiftUI and it originally started with creating a new project as an "App" (Xcode, clicked on file, new, project, click on "App") but was then later asked to put it into a pod as a framework. I did it successfully (Xcode, clicked on file, new project, click on "Framework"), however I am unsure what the differences are and I'm unsure why I would want to do that. To me they look very similar, except that I'm unable to launch my project as a framework in the simulator. Luckily SwiftUI offers the canvas preview window however it is a bit finicky when it comes to certain button interactions, which is why I am wanting to use the simulator.
Two places of confusion:
What is the difference between an app and a framework project?
Why is it more advantageous to have my project as a framework?
An App is a standalone application that can be launched and run. For example, all of the apps that you have on your phone are just that -- apps. You tap on them and they launch and run, presenting a user interface, accepting input, etc.
A framework is something else entirely. It's a collection of code that is bundled together into a package that is used by another framework or by an app. Some frameworks are provided by the system -- for example, SwiftUI is a framework that it sounds like you're using in your app. Other frameworks are provided by 3rd parties. For example, you can find many frameworks via CocoaPods or the Swift Package Manager -- Alamofire is a common example. Also, you can make your own frameworks and use them in your own code as a form of organization and separation of responsibilities.
Why is it more advantageous to have my project as a framework?
It is not -- they are two almost completely different concepts (besides both ultimately being collections of code and resources). If you intend to build an app that is launch-able on someone's device, your only choice is to make an app. If you intend to make a collection of reusable code for use in your or someone else's app, than you would make a framework.
Excellent answer (and upvoted) by #jnpdx. Let me give you a physical example:
(1) Create a project in Xcode that is a framework. Call it "MyAppKit". Inside it create, well, basically anything - a View, UIView, or more likely a function that will be shared by several views. (Let's go with that.)
public func setLoginName(_ login:String) -> String {
return ""Hello, " + login + "!";
}
Pretty simple. Call it, pass in something, and it returns a string saying hello. Please note the public piece. It matters. (And there's much more there. This is a simple example.)
(2) Now we get to your app or apps. Let's say you have two apps that need to use this (again, very simple) code. One is SwiftUI, one is UIKit. (It doesn't matter except for syntax.) Sine my forte is UIKit I'll use that. (And it can be several dozen apps too.)
import MyAppKit
let myLoginMessage = setLoginName("World").
Pretty much, it's "Hello, World!'
Again, this is really a nonsensical example. But it should get you started on what the difference in Xcode is between a Framework project and an App project is.

Create Framework / Library / Module of Swift Objects in Xcode

I am a (very) novice iOS/Swift programmer with a basic question about moving reusable software objects to their own ... something.
I am developing three iPhone apps that present information from three distinct data sets. Those data sets contain unique information but are structurally similar. As such, the apps share some Swift classes that are identical, specifically the classes that model the data. As I continually refactor the code, I find that when I tweak a class in one app's project, I have to remember to go to the other two projects and make the same tweaks to the same classes for those apps. It's getting to be a big headache.
What I would like to do is have one class definition in its own ... something that I can share, link, import, or attach to/from each app's project. From my online research, I suspect that the ... something is a library? or maybe it's a framework? or a module? I have found all three terms are used, but I am not sure how they relate to each other.
Given that all of the software I am writing is in Swift, does Xcode support what I am trying to do? Thank you!
It seems you have the issue of needing the same Swift class in multiple projects. You could build a Framework (aka Module) for this class then copy it in to each project. This is probably the formally correct approach but it is a bit of overkill for just a single class.
Instead, you could just make the file in the Navigator panel a reference in each project to the one actual file.
You could also make a Workspace and then put each project into the workspace and just have the file at the top level (but this may introduce some build complexity).

Typhoon DI on storyboard integration

I'm new to Typhoon. I'm reading documentation to inject dependencies into my storyboard's view controllers. I have basic understand of how the framework does the DI on classes, but storyboards seems complicated. I have read both storyboards and PList integration documentation but I'm kind of confused.
This may sound silly and obvious. If my storyboard filename is Main.storyboard, in my plist I'd add key UILaunchStoryboardName with value Main.storyboard?
What would be the value for key UIMainStoryboardFile?
Do dependencies get injected automatically or how do I specify which dependencies get injected into each of my storyboard's view controllers?
I was unable to find an example or tutorial that uses storyboard (and since most of them are in objc and I'm working with Swift, it's kinda hard to follow up every step, so I apologize in advance if these questions are silly
To answer questions one and two, if you create a project from Xcode specifying to use storyboards, then those values will already be completed in your plist. If you have a legacy project, this is a nice way to see what those values should be.
As for question 3, if you 'annotate' your storyboard view controllers with auto-injection macros, then dependencies are indeed injected automatically. For non-storyboard view controllers then to have dependencies injected, an instance should be obtained from Typhoon, just like in the Quick Start.
Note that you can inject the assembly itself into a view controller, in order to load an injected object graph 'on demand'.

Cocos 2D GUI & Xcode 5

I have an iOS game app that was created in Cocos 2D & Box 2D by an outside developer where I need to make some minor UI modifications (nudging platforms, item positions, etc.).
Normally, to get a visual view of the app in previous versions of Xcode, you would go to the .xib file. In Xcode 5 this is supposedly replaced with main.storyboard. Though I can build & run my project in the simulator or as an .iap file on my device, I cannot figure out how to make corrections to graphics (re positioning) as I would normally do. The main.storyboard file doesn't exist in my project.
Current file extensions represented:
.h, .mm, .cpp, .cmake, .pch
Thanks in advance.
Most cocos2d apps position "graphics" in code. Storyboard and xib files are not used at all for visual layout of cocos2d elements (nodes).
At best you'll find ccb or ccbi files which would indicate that CocosBuilder was used to design the scene's layouts. If there are no such files, you have to look into and modify the code.
If it was created in cocos2d/box2d, there are any number of ways that the presentation could have been created. Usually these don't involve storyboard/.xib files for cocos2d/box2d.
All the files you listed are standard code files; I don't see any graphics files (.png, .pvr, etc.) or physics editor files (.pes) in your list, or CocosBuilder files (ccb/ccbi). There are probably more file extensions in your project that you may want to find. You could potentially list out all the file extensions in your project, and maybe somebody on SO will be able to help you identify the tool or tweak the code by posting it.
However, I think the best option is to find a developer familiar with these technologies, let them take a look at the code, and get you back on track.
You may type a lot into SO and wait a long time for an answer to something a good developer could find for you in a few hours. If this is an academic (no commercial project), they may do it for free. Or for a nominal fee for a commercial project. Or for good will. Or the fun of it. etc.

Can I build RubyMotion apps with Interface Builder?

Ruby Motion just came out, and the screencast doesn't seem to say anything about whether or not you can use Interface Builder to build your interfaces and integrate them in your RubyMotion project. Is such a thing possible? Or do I really have code everything by hand, not to mention maintain to different pieces of code for iPhone/iPad?
My rep isn't high enough to create a rubymotion tag, so please help out if appropriate.
I'd just like to point out that RubyMotion 1.3 now support automatic compilation of .xib files that you put into the resources folder. So now the workflow becomes :
Create your .xib file using XCode (no need to create a project, just use File|New...|File) and save it into the resources folder. As there is no support for outlets yet, be careful to set the tag property for each control you want to use in your code (you'll find in the property sheet of each component under the "View" header).
RubyMotion will take care of compiling your .xib file into a .nib file, so enjoy :)
In your UIViewController derived class, load the nib using loadNibNamed:owner:options:, as shown below.
In viewDidLoad, fetch your various components using viewWithTag: and add events handlers using addTarget:action:forControlEvents:,as show below.
As a bonus, next time you want to edit your xib, just do open resources/MyView.xib, it will only launch the good parts of XCode.
class CalculatorViewController < UIViewController
def loadView
  views = NSBundle.mainBundle.loadNibNamed "Keyboard", owner:self, options:nil
self.view = views[0]
end
def viewDidLoad
button = view.viewWithTag 1
button.addTarget self, action:'buttonTapped:', forControlEvents:UIControlEventTouchUpInside
end
def buttonTapped(button)
# ...
end
end
Yes you can use Interface Builder in RubyMotion.
.xib files that are located in the resources directory are automatically compiled into .nib files and available to your project.
There is even a way to support outlets if you are so inclined :
https://github.com/yury/ib#readme
http://ianp.org/2012/05/07/rubymotion-and-interface-builder/
But if you really want to use IB then you could still probably use it to lay out your UI and just call
NSBundle.mainBundle.loadNibNamed(MY_NIB_NAME, owner:self, options:nil)
or similar. I don't think that RubyMotion does any name mangling so you can use your ruby classes in IB by explicitly setting them.
You can probably build the interface in IB and call the command-line tools to compile the XIB to a NIB.
However, you aren't going to be able to connect outlets or assign actions because IB can't parse the Ruby source files for the IBOutlet and IBAction tokens. Normally, the NIB loading code makes those connections for you after loading your NIB. You'll have to do that yourself, in code.
Of the two glaring weaknesses in RubyMotion, to me this is the worst. (The other is that lack of code completion will make writing to the Cocoa APIs really tedious.)
Cappuccino had the same problem. They developed a tool called XcodeCapp: https://github.com/cappuccino/cappuccino/tree/master/Tools/XcodeCapp
It creates "dummy" Obj-C files that you can connect your outlets and actions to in IB, automatically parses them in the background and enables you to use IB to layout your Cappuccino UIs.
It should be possible to take a similar approach with RubyMotion (if you really want to use IB).
Johannes
There is someone who has made that:
Here is a tutorial video: https://www.youtube.com/watch?v=cOapNvehbg4
And this is the website https://github.com/yury/ib
Extra-Tipp: To find wrappers for rubymotion check this source
http://rubymotion-wrappers.com/
Hope this helps

Resources