selecting the correct target when creating a new WKInterfaceController - xcode

Normally when you create a new WKInterfaceController you just select the WKInterfaceController class and Swift/Obj-C. But the next screen gives you 3 options for choosing the target; iOS app, WatchKit App and WatchKit Extension. It is defaulting to the iOS app for me so I am concerned that maybe I selected the wrong targets for my previous classes.
How do you know what target to select? Is it usually always the WatchKit Extension since that's what we're obviously putting our classes in? It seems obvious I know but I want to make sure because I often get confused with what targets to add binaries, classes and everything else to.
If I have made a mistake in choosing the target for a new WKInterfaceController.swift file where do I fix it? Would I fix it in Build Phases -> Compile Sources?
Apple says here when creating a WKUserNotificationInterfaceController to add it to the WatchKit Extension target. But does that apply to our own custom WKInterfaceController classes as well?

You'd add it to the WatchKit Extension.
Notification controller, glance controllers, complication controllers, and interface controllers all run in the extension.
An interface controller runs in your WatchKit extension and remotely manages the behavior associated with an interface controller in your Watch app’s storyboard file.
If you made a mistake and added it to the wrong group, you'd correct it in that same (Utilities File Inspector) pane, by simply unchecking the wrong target, then checking the proper target.

If I start adding a file by double clicking on the WatchKit Extension, then it defaults to choosing the WatchKit Extension for the location of the file. Do you perhaps choose New File from the top menu? It probably doesn't default then.
So yes, you should add WatchKit user interface classes like this to the WatchKit Extension.
As to 2), you can change file membership in the file properties on the right pane, using the File Inspector. You'll see a Target Membership check box there. This will change membership, but as I remember it will not move the file on disk, so just be aware of that if you do it this way.

Related

How to share Swift classes across multiple targets of one Xcode workspace?

I'm using Xcode 9 and Swift. I've got one workspace and one iOS project. Later I added a MacOS target (Cocoa App). When I try to reference a class from the MacOS target to the iOS target, the compiler says:
Use of unresolved identifier.
How do I get Xcode to allow me to share Swift classes from target to another?
This type of Xcode workspace organization is mentioned in Apple's documentation but doesn't describe how to allow the usage of implicit dependencies within Xcode.
Use Project Navigator to find the classes you wish to share with another target. Highlight the classes. Open the inspectors (icon in the top right corner of Xcode). On the right side a panel will appear. Change the "Target Membership" to include the other (in this case, MacOS) target.
After a rebuild it should work fine.

How to include support documents in xcode cocoa app?

In iOS version of app, sample/template files are added to Xcode in a group and then become a directory of that name within the app bundle. Easy enough.
What is the Cocoa equivalent? When I try the same thing, Xcode (Swift 3) fails on build with a "Command /usr/bin/codesign failed with exit code 1". How does one add support files (or directory of files) to a Cocoa app?
In macOS, I guess you mean that, every App creates a Resources Folder inside the NSBundle. Just check with right click "Show Bundle Content".
If you add resources to Xcode, just by dragging the file anywhere in your project navigation, will be asked to copy that file if needed.
I usually create a group with Supporting File, but thats arbitrary, because it has nothing to do with the file structure inside the project folder on disk nor with the product package.
To create groups just right mouse and select group.
This copies the file inside the Xcode project Folder. And if you choose to add target, then the file will be included to that Resource folder.
You can ask for that File with:
let bundle = Bundle.main
let path = bundle.path(forResource: "Test", ofType: "txt")
Edit
if you have to code sign your resources, then ope the copy files menu in Build Phases, add with the plus button your resource and check code sign on copy. This should provide a proper signing for your resource.
Hope it helps!

What is the effect of specifying the Target of an Objective-C class in Xcode?

What is happening when I specify the project (or test) when I click this selection?
I can't seem to find a a good resource explaining why I have to select the targets, only that in order to use my class, I must have a target associated with the class.
Targets basically specify the product that should be built. Your app could have multiple targets. I.e. a keyboard extension is a target and the main app for the keyboard extension is another target. If you have a class that is to be used in one or the other products, you must specify its target.

How to build and embed another application inside my target in Xcode?

I have an application in my project (named App_Main). And I want to package another tiny application (let's call it App_Tiny) inside the package of App_Main.
Then, as I know App_tiny's path, I can execute App_Tiny programmatically in App_Main's run-time when I need that.
How can I achieve this? How to specify and build another executable target, AND, most importantly, automatically put App_Tiny inside the package directory of App_Main?
For adding a new target it's as easy as hitting the "New Target" button in the left hand pane of your project explorer. Xcode will allow you to choose the target type (Application) when you add it.
Next you need to add FooBarTiny as a build dependancy for your main app (FooBar). Edit the Scheme for your Main Target and add the sub target as an explicit dependancy.
Now when you build FooBar; FooBarTiny will be built if it needs to be.
Next you add FooBarTiny into the "Copy Bundle Resources" phase. Hit the add button and scroll down the tree and you can find FooBarTiny in the Products folder.
To launch FooBarTiny from within your app you can use NSWorkspace.
- (NSRunningApplication *)launchApplicationAtURL:(NSURL *)url options:(NSWorkspaceLaunchOptions)options configuration:(NSDictionary *)configuration error:(NSError **)error would probably be a good start point. Check the API docs for other variants.
EXTRA FOR THE APP STORE
It's not enough to sign your main app. Any Applescripts and sub-apps (FooBarTiny) will have to be signed as well or your app will fail validation. This answer isn't about that but theres a good blog on the issue here.

XCode Unknown class ***** in Interface Builder file

In an app, suddenly it's giving me the error XCode Unknown class ***** in Interface Builder file. I reviewed everything, storyboard, classes, etc.
I try to rename the class but it is the same problem, even I created a new class and copy the code in. I think XCode is taken that from a kind of cache because even properties that I deleted like the icon in the tab bar item are still present in the app when I run it.
What can be the problem?
Also if using a static library, don't forget to add the -ObjC flag to Other Linker Flags in your projects Build Settings tab.
If you have failed to do so, "Unknown class ... in Interface Builder file" will occur when trying to load a view controller from the static library in IB.
Just another case I experienced the error will show.
I faced a problem when I created a project with the same name that already existed in my projects directory (though it was deleted some time ago). Xcode didn't understood that it's a new project and use build directory of old project as a build directory for a new one. I didn't knew how to completely rebuild project from scratch and I just removed a build directory.
In my case I removed /Users/username/Library/Developer/Xcode/DerivedData/ProjectName-suffix. You can find it in Xcode in Project navigator on the left by selecting ProjectName->Products->ProjectName.app and File inspector on the right will show you a full path to file.
Sorry, after trying several post I found one solution, delete the folder of the simulator in /...Library/Application\ Support/iPhone\ Simulator/ and removing the class and re-adding it.
You will need to add to your targets Other Linker Flags as well, just adding to the Project Build Settings does not seem to work.

Resources