Using the same file with different flags in WatchKit and host App - ios

I'm trying to use the same code in both my watchkit extension and host App, but with some additional code in the host App and some additional code in the watchkit extension. To do this I've added WATCH and APP swift flags on the respective targets. Problem is, when I look at my code with my App scheme selected, it doesn't syntax highlight the APP code but does highlight the WATCH code, and other code that refers to the APP code then fails to compile.
The watchkit extension is a target dependency of the App so I'm guessing it's something like it is compiling the code for the watch and then using the same compiled code for the App, although in the compile results I can see it is compiling with the correct flag and can't see any overlap between watchkit and App build paths, any ideas?

SWIFT version
Use other swift flags in build settings of your WatchKit Extension target. For example, add a flag WATCH (must be prefixed with -D):
Then in your shared file add this code:
#if WATCH
NSLog("watch")
#else
NSLog("app")
#endif
Objective-C version
Use preprocessor macros in build settings of your WatchKit Extension target. For example, add a macro WATCH = 1:
Then in your shared file add this code:
#ifdef WATCH
NSLog(#"watch");
#else
NSLog(#"app");
#endif

Related

Framework Not supported in Simulator - Make Dummy Framework

I have a framework which is not available in simulator, So not able to run in simulator. Im getting below error.
Could not find module 'Framework' for target
'x86_64-apple-ios-simulator'; found: arm64, armv7-apple-ios,
arm64-apple-ios, arm, armv7
How can i create a dummy framework or is there any way to make it run on simulator. Just like simulator is handling camera like functionalities.
Tried below code: But how to define the else condition.
#if (arch(x86_64)) && os(iOS)
import Framework
#else
#endif
I work for a team that has developed a framework that does not work in simulator (uses camera) but includes the simulator architecture so a developer can use it regardless the device. We only have two entry points and in each of them we put the following code:
#if TARGET_IPHONE_SIMULATOR
return nil;
#else
// code goes here
#endif
I know that this is not ideal and we just return nil (simulator is the only possibility of returning nil), but at least you can call it and if nil do something else instead of crashing or just not compiling at all.
You might create a second target without the framework. I do not know how many files use this framework?
If there are not many you can create a duplicated file only available to the second target. Of course, you have to remove any code referencing to this framework in the duplicated file.
This approach should work.
Xcode has different build system for simulator and real devices. So it will generate different app for both. If you select any Simulator target then it will builds app for simulator and if you select Generic iOS Device or any real device target then it will builds different build.
You are using that framework which are builded for simulator target, So follow this steps,
Download that framework's code in your system.
Add project files of framework in your workspace. For that you can refer this and this.
If you don't want to add whole code of framework in your project then you can add particular( for device or simulator ) build of framework in your xcode project. For that follow this steps,
Open your downloaded project of framework.
Select any simulator target and build project.
Get generated .framework file from Products folder.
Add this framework in your project like this.
Now build your project for simulator.
Follow above steps for devices target if you want to build for devices.
I hope this will work for you.

Apple Watch for Multiple target

I have multiple target in my App like QA,Release,Develop and i want to create watch app for all targets I have already added watch app for QA target and my question is How can i use same classes and storyboard for other targets e.g Release and Develop.
Thanks
You should create a Framework, in which you include all classes and files that you need to access from each target and then include the framework in your targets. Embedding Frameworks in an app
I think a watch app target can only have one companion iOS application. Different target (QA, Release, Develop) means different bundle ID. Watch target bundle ID has to match companion app's bundle ID as its prefix.
For example, com.xxx.yyy.watchkitapp has to have an iOS companion with com.xxx.yyy. Therefore I think it's impossible.
However, if your code base for all targets are roughly the same you can have single target with multiple build Configurations.
Inside Build Settings for the single target, you can set different flags for Preprocessor Macros.
In code, you can do something like this to differentiate each build configuration.
#if QA
// enable QA feature
#elseif RELESE
// disable beta features
#else
// enable everything
#endif

Accessing a class of iPhone app in Watch App

I want to use my already developed NSObject Class in watch app (Watch App target is added to same project).
My iPhone App is written in Objective-C and now I am using Swift for Watch Extension, so I created a Bridge-Header to use this class in Watch App and add the class to Watch Extension target. When I build the app, it gives me many errors from other classes with this reason:
Cannot find interface declaration for UIControllerView, SuperClass of xxxxClass
And all these error files seem that they have a target of WatchKit Extension, but I didn't include them. On these files, Target Membership Watch Extension is also unchecked (means not a target of extension). Here are the Classes which I didn't added to Watch Extension, but they are running as a Watch Extension class.
You will need to select that class and check Target membership for WatchKit extension From file inspector.
For Swift class :
For Objective-C class you make it for .m file
You have the check the targeting files are added or not.
For that:
1.select your project file -->Build Phase-->Compile Sources.
-Check the file present or not.
2.if not just remove and add the files that are all missing in compile source.
3.Clean and Build your source..

Cocoa Touch framework shared between iOS and tvOS

I'm working on an app that can have some shared code that I want to encapsulate in a framework. I created iOS Putter app target, then a framework PutterKit that I link from the app. This works fine.
Then I create a tvOS app target PutterTV and duplicate the PutterKit to PutterKit (TV) and set its sdk to tvOS
When I import PutterKit in the tvOS app and compile it, I get the error
No such module 'PutterKit'
Here is a sample project
https://dl.dropboxusercontent.com/u/1326174/Putter.zip
What is the correct way to setup such a framework?
Looking at your project, you need to:
import PutterTVKit
If you look at your PutterKit(TV) target build settings, you will notice that the ProductName and ProductModuleName are PutterTVKit.
Also make sure that in the Linked Frameworks and Libraries section in PutterTV app target, you link in PutterTVKit.framework (not PutterKit.framework).
With these changes, it appears to compile fine.

Including certain Objective-C files based on scheme in Swift project

I am using SimulatorStatusMagic to change the status bar within the simulator when automating my screenshots. I cannot include this within non-screenshot builds due to the code not working on devices and using private APIs, restricting a submission to the app store. The project files are included directly in the project, without the use of a framework, due to the app targeting iOS 7.
Within the Objective-C Bridging Header I have:
#ifdef SNAPSHOT
#import "SDStatusBarManager.h"
#endif
I then have a separate release name "snapshot", which has the follow values:
Preprocessor Macros: SNAPSHOT=1
Other Swift Flags: -D SNAPSHOT
Within my app delegate I then have:
#if SNAPSHOT
SDStatusBarManager.sharedInstance().enableOverrides()
#endif
I (incorrectly) thought that this would allow me to submit to the app store since the code would not be compiled but I was wrong. Is there a way to only have this code included in snapshot builds?
My guess is that, even though you are only calling the library when building with the 'SNAPSHOT' flag, the library binaries are still being linked with the app, and thus being rejected by Apple.
SimulatorStatusMagic's readme says you should add it to the project only when on Debug mode to avoid that, and your Podfile settings should also reflect that.
pod 'SimulatorStatusMagic', :configurations => ['Debug']
Reference: https://github.com/shinydevelopment/SimulatorStatusMagic#i-have-a-script-to-take-my-screenshots-can-i-automate-this

Resources