How to structure a Cocoa project - cocoa

When I write in Python I can structure my source code as several files and folders, effectively creating the modules. I then can import a module, a file can have several classes, and so on.
How to structure a project written in Cocoa? Can a .m file implement multiple classes? Is there a notion of a "module"? What exactly is a "framework" for? Is it possible to create a framework of mine? How do I "import" it into another project? And what happens at compilation time, does the compiler embed frameworks into one giant executable or are they living next to the executable, merely being copied into the bundle folder?

It really sounds like you should start with some Apple resources like Your First Mac App and What are Frameworks?
To answer your questions specifically - a .m can contain multiple class implementations; a Framework is a bundle of shared resources; a Framework is a library for reuse; you can create your own Frameworks; in a typical Mac application bundle the frameworks are copied into the application bundle.
There are also a bunch of good resources concerning the structure and design of Cocoa applications - I particularly like this Cocoa With Love post.

Related

Xcode create shared framework across lots of targets

I'm making stuff for IOS, Mac, and WatchOS - I have certain common functionality that is more about me and the way I program than about whatever it is I'm programming - helper methods etc
What I'd like is to have a "Common" framework or library in my app which is included into every other library. I understand I need a separate target for each of ios, macos, watchos, but I can't figure out how to set it up.
I can create a framework - and it comes with a target - I can duplicate that target and change stuff, but I don't seem to be able to change it from IOS to macos for instance. I can create a separate macos target, but then I can't seem to be able to change where it gets the code from.
Essentially in my source tree I want a single directory:
Common
and then have target frameworks CommonIOS, CommonMacOs, CommonWatchOS - that all just compile "Common". How do I achieve that?
You're misusing the word "framework". All you want is to keep some source code as a library that all your projects and targets, no matter what system they'll be compiled for, can use. You are describing a Swift package.

Dividing a Swift application's components into Swift modules

I'm writing an iOS application in Swift, and I'm trying to figure out how to organize the project into separate modules. I'm using an MVVM architecture, and I want to make the Model, ViewModel, and View components separate Swift modules that make only subsets of themselves accessible to the modules that import them. The files in the View would import the ViewModel, and files in the ViewModel would import the Model. How can I accomplish this? Note that I'm not trying to create libraries that multiple applications can share. I'm just trying to enforce separation of components using modules.
EDIT: Maybe the question is, "What mechanism should I use to create modules aside from the one that comes with the initial iOS application project?"
One of the answers in "How do you use Namespaces in Swift?" https://stackoverflow.com/a/24032860/215400 says, "classes (etc) are implicitly scoped by the module (Xcode target) they are in." From that, one might conclude that targets correspond to modules and that the answer is to create separate targets within an Xcode project, but I tried that earlier, and tskulbru is saying that I need multiple Xcode projects.
Regarding multiple Xcode projects, the File > New > Project > iOS Framework & Library > Cocoa Touch Framework option didn't look right because it's supposed to be for things that use UIKit, and two of the modules I want to create shouldn't depend on UIKit. The other "Framework & Library" option, Cocoa Touch static library, isn't an option with Swift.
Another StackOverflow post mentioned using private Pods. After spending an hour working on that, I concluded that it wasn't the right solution because I shouldn't have to edit these modules in different workspaces.
This isn't possible without creating separate projects for the modules you want to create. This is because the way Swift handles namespacing.
Eonil answered this better than me: https://stackoverflow.com/a/24032860/215400
(Copy below)
Answered by SevenTenEleven in the Apple dev forum:
Namespaces are not per-file; they're per-target (based on the
"Product Module Name" build setting). So you'd end up with something
like this:
import FrameworkA
import FrameworkB
FrameworkA.foo()
All Swift declarations are considered to be part of
some module, so even when you say "NSLog" (yes, it still exists)
you're getting what Swift thinks of as "Foundation.NSLog".
Also Chris Lattner tweeted about namespacing.
Namespacing is implicit in swift, all classes (etc) are implicitly
scoped by the module (Xcode target) they are in. no class prefixes
needed
From my perspective if you want to encapsulate your components, probably you have two solutions:
Framework
Internal cocoapods
Both solutions will give you fully encapsulated modules, where you can define API that will be available in project through public keyword.
All other things will be not visible in your core project.
Managing your project will cost you a lot more time, but if you write this using SOLID principles, probably you will get more reusable code and those frameworks could be imported to other project just using import definition.

In Swift, what are my code reuse options for designing console applications, and how do I implement them?

My current code base involves writing console applications in C++ where I import a static library containing many common classes.
I would like to move to Swift and replicate this process. However, I have come across a couple difficulties:
As it stands, one apparently cannot create static libraries in Swift.
As it stands, one apparently can not import a framework into a Swift console application.
Currently I have been experimenting with writing a single view application and importing Frameworks that way, but enough has gone wrong that I would really like to simplify that and stick with console applications.
Given that, so far it appears that my only option for code reuse is to keep Swift files in common directories and drag them as needed into the console application. Since these console applications are for my own use and I'm only interested in the data they generate (i.e. I don't actually give the program to a user) this is actually a workable solution. I was hoping, however, there might be something a bit cleaner.
Any other suggestions on what to do for code reuse for pure Swift console applications, and if so, how do I go about doing it?
You can create a standard Swift framework that contains your common classes, and then create a console application that lives in a bundle. This will allow you to copy the framework into the bundle's framework folder which your console application will have access to at run time.
You can find more details about this approach in Alsey Coleman Miller's article about using embedded frameworks in OS X command line applications.
The downside, of course, is that your console application now lives inside a bundle.

What are the advantages/disadvantages of Cocoa frameworks, libraries, and bundles?

I have the following requirement.
I need to implement dll kind of thing on mac.I need to create a backend library which can be loaded dynamically.This backend library will contain the cocoa classes and c++ classes.
What is advantage/disadvantage of cocoa framework,I was googling so far,I was not able to figure out the best one.Please give me some suggestion.Is cocoa framework also loaded dynamically?
The main difference between a dynamic library and a framework is that a framework can contain resources (images, sound files, nibs, etcetera) and header files. When you use a dynamic library, these are separate.
Both a framework and a dynamic library are loaded at runtime. If your library will only be used on Mac OS X, I recommend creating a framework because it is easier to manage since everything is in one folder.
Bundles (the white LEGO bricks) are almost exclusively used as plug-ins. If you want to create a plug-in interface you should accept bundles and you should provide a framework the bundles can link against. Bundles are also loaded at runtime.
Here's a decent tutorial (PDF form) that goes a little more in depth explaining the differences between ordinary libraries and frameworks.

What steps are involoved in loading a .Framework under MacOS X?

I am realtivly new to the concept of dynamic loading and shared libraries. While I fully understand how dlopen() could be used to reference symbols in a shared library I have yet to fullt grasp what MacOS does behind the scenes when I don't statically link against something. When adding a framework to Xcode I have the option to load it into my project or I can just provide some form of symlink to it(the actual implementation is obfuscated be the easy to use interface).
There after all I seem to need to do is import the header files that porvide and API to these frameworks and I can just invoke their symbols free of hassle. Can someone explain to me what I am actually doing, because it make no sense to me.
The sheet you're referring to has nothing to do with the actual linking of the framework. The copy vs. link choice refers to how you want to include the framework in your Xcode project, not your app binary.
For system frameworks there really isn't anything you need to do but import the headers.
For custom frameworks (your own or third-party) the framework must reside at the load path directory when your app launches. Typically the load path will point to your app bundle's Frameworks (sub)directory, so you must add a Copy Files build phase that copies the framework to your app bundle's Frameworks directory.
Remember to check out Apple's Framework Programming Guide, especially the section on frameworks embedded in your app bundle.

Resources