TARGET_OS_IPHONE and ApplicationTests - xcode

Why doesn't this code work when compiling an ApplicationTests unit test bundle?
#if TARGET_OS_IPHONE
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#else
#import <Cocoa/Cocoa.h>
#endif
One of my dependencies has this check and compiles just fine in my main application bundles, but it tries to load <Cocoa/Cocoa.h> when compiling my ApplicationTests bundle. It's probably just my lack of understanding of Xcode, but I get nervous when my test bundles don't build. Any suggestions?

You need to add
#include <TargetConditionals.h>
source: https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-8A428/TargetConditionals.h.auto.html

The simplest solution is to move the #import <Foundation/Foundation.h> statement out if the #if condition and replace Cocoa with AppKit like this:
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#else
#import <AppKit/AppKit.h>
#endif
The Foundation umbrella header imports the NSObjCRuntime header which in turn imports the TargetConditionals header.

I had a similar problem: TARGET_OS_IPHONE isn't defined when building a static library. My solution was to add "-DTARGET_OS_IPHONE" to the "Other C Flags" section of the target build options.

Both work well
#import "TargetConditionals.h"
#import <Foundation/Foundation.h>
<Foundation/Foundation.h>
|
└-#import <Foundation/NSObjCRuntime.h>
|
└- #include <TargetConditionals.h>
|
└- defined TARGET_OS_IPHONE

The solution for me in Xcode 12.5 is to add TARGET_OS_IPHONE or TARGET_OS_IPHONE=1 to GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS in build settings or in an .xcconfig file.
Details:
After updating to Xcode 12.5 beta, now carthage bootstrap will fail when trying to build iRate 1.12.2. I looked in the carthage build log, and the error responsible for the failure is:
error: 'TARGET_OS_IPHONE' is not defined, evaluates to 0 [-Werror,-Wundef-prefix=TARGET_OS_]
The problem for me is that iRate is no longer under development, and I'd rather not fork iRate it just to override some broken build setting.
However, there is a nifty workaround trick that I learned from the folks over at Carthage: you can override the build settings of any project using any .xcconfig file by setting an environment variable, XCODE_XCCONFIG_FILE=path/to/my.xcconfig before running xcodebuild. Any settings in that .xcconfig file will now override the settings of whatever project you're building with xcodebuild.
Furthermore you can do this dynamically by a script that you call instead of calling xcodebuild, e.g.:
#!/usr/bin/env bash
# Save this script as 'injectXcodeBuild.sh'
# Run it in place of xcodebuild (all arguments get forwarded through)
# The echo'd commands below will override any settings of the
# projects that get built by xcodebuild through this script.
set -euo pipefail
xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX)
trap 'rm -f "$xcconfig"' INT TERM HUP EXIT
echo 'GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS=TARGET_OS_IPHONE=1' >> $xcconfig
export XCODE_XCCONFIG_FILE="$xcconfig"
xcodebuild "$#"
Alternatively instead of xcodebuild this script could call carthage if you're needing to override some Carthage dependency's build settings. It might also work for CocoaPods pod command (I'm not sure).

Note: in Swift one must use:
#if os(iOS)

Related

How can I prevent SASS variables from being overwritten in Foundation?

I have installed Foundation SASS using Bower. Then I have imported foundation and initialized it by the following commands on my main.scss:
#import "../vendor/foundation-sites/scss/foundation.scss";
#include foundation-everything(true); // Init the foundation
The problem is that, there's a setting file, _settings.scss, that foundation.scss import which I need to override. Since I shouldn't touch the files inside Bower directory,vendor/, I need to make those changes on my main.scss. And no, the _settings.scss doesn't make use of the !default functionality. A snippet of how the settings are defined is as follows:
$global-font-size: 100%;
$global-width: rem-calc(1200);
$global-lineheight: 1.5;
Is there any way I can define a variable before the include just so that it doesn't ever get overwritten? Something like..
$global-font-size: 16px !important;
$global-width: 1000px !important;
$global-lineheight: 1 !important;
#import "../vendor/foundation-sites/scss/foundation.scss";
#include foundation-everything(true); // Init the foundation
Two cases, two way :
You must maintain a package in bower
I will use symbolic link to make things easy. Take a look about my project files.
I have install foundation with bower :
bower_component/foundation/scss/{...whatever}.scss
Then I would create a symlink to .bower_component/foundation/scss folder.
src/scss/foundation # this is a symbolic link to -> ./bower_component/foundation/scss
And I copy files I want to customize out of bower_component.
src/scss/my_settings.scss # copied from foundation/scss folder
And I add my own scss.
src/scss/main.scss
which import all my customization and foundation.scss all together
#import 'my_settings' ;
#import '...other_customization...'
#import 'foundation/foundation' ;
Then build src/scss/main.scss, and everything works well.
Then you can maintain foundation version with bower without worries. No matter what changes in bower_components/foundation, just make sure the folder name and relative path is right, everything will be fine.
Well, the version is not so important.
Ask yourself a question. What benefit you with foundation being maintained by bower? If there is no good reason for you, you could just move foundation out of bower_component folder and do any change you want.
Bower doesn't prescribe to the user its own build system, or to the
developer a method of including libraries (AMD, CommonJS, etc.) All
Bower does is install the right versions of the packages that the
project needs and their dependencies. In other words: it downloads
source files for the right libraries and everything they need into a
special folder. Everything else is up to the developer.
Quoted from : Artem Sapegin

Xcode Archive Build Fails

I have an Xcode 7.2 project that succeeds when building/running against the local device Product|Build. The main project include a reference to InAppSettingsKit project. When I try Product|Archive the build fails. Any help or suggestions will appreciated.
The main project has a bridging header file to InAppSettingsKit project. The problem seems to be that the header file referenced in the bridging header file is not found.
Bridging Header File
#ifndef Screen_Saver_Killer_InAppSettingsKit_Bridging_Header_h
#define Screen_Saver_Killer_InAppSettingsKit_Bridging_Header_h
#endif
#include <UIKit/UIKit.h>
#import "InAppSettingsKit/IASKViewController.h"
#import "InAppSettingsKit/IASKAppSettingsViewController.h"
#import "InAppSettingsKit/IASKSpecifierValuesViewController.h"
#import "InAppSettingsKit/IASKSpecifier.h"
#import "InAppSettingsKit/IASKSettingsReader.h"
#import <iAd/iAd.h>
As requested, here is the search paths of the main project:
(I noticed InAppSettingsKit.xcodeproj is in red; does that mean anything ?)
My problem was with InAppSettingsKit. Their website says: for Archive builds there's a minor annoyance: To make those work, you'll need to add $(OBJROOT)/UninstalledProducts/include to the HEADER_SEARCH_PATHS
This wasn't quite right either.
I think this is a bug in XCode 7.2 + Swift with Obj-C dependencies when archives are built.
I now know way more about xcode than I ever wanted to.
First you need to go through the install logs to find out where things are being built. On my installation $OBJROOT points to:
/Users/jlongo/Library/Developer/Xcode/DerivedData/PROJECTX-bmyyngijghtekdgqqfnabonhpuxo/Build/Intermediates/ArchiveIntermediates/PROJECTX/IntermediateBuildFilesPath
There I found the header files in the path:
.../IntermediateBuildFilesPath/iphoneos/include/InAppSettingsKit/
So my resolution ended up being (non-recursive)
$(OBJROOT)/UninstalledProducts/iphoneos/include
Interestingly, $(OBJROOT) or other recursive paths shorter than this one did not work.
Also I placed this setting in:
Main Project|**Targets**|Build Settings|Header Search Paths
setting it here will not work:
Main Project|**Project**|Build Settings|Header Search Paths

What does the exclamation mark after a SASS import mean?

For example, this is in the codebase I'm working in:
#import core/mixins/retina-sprites!
What does this mean?
That is not part of the core Sass syntax. The only add-on I am aware of that uses that syntax is the import-once plugin:
#import "something";
#import "something!"; // this will be imported again.
The plugin prevents files from being imported more than once, but exclamation mark overrides this allowing you to import the file again. This plugin used to be a stand alone extension, but is now bundled with Compass by default.

RCT Linking Manager file not found

I want to use react native library RCTLinkingManager which shows up in menu under "Libraries > RCTLinkingManager.xcodeproj".
However when i add it to iOS/AppDelegate.m like so:
#import "RCTLinkingManager.h"
// #implementation ...
Build fails with 'RCTLinkingManager.h' file not found. I tried to clean the product and clean build with no luck.
You have to add $(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS to your "Header Search Paths" in the Build Config of your project. You can find more info on the official React documentation
Kindly make sure that you place the
#import <React/RCTLinkingManager.h>
in the Appdelegate.m file above the
#ifdef FB_SONARKIT_ENABLED
it worked for us.
I had a similar issue only when I've done the archive/release version... that happen because the import was made under the #if DEBUG. So make sure you put the import in the proper place otherwise you can get Use of undeclared identifier 'RCTLinkingManager' error
Anyone who is facing this issue for a react-native archive for ios platform just place
#import <React/RCTLinkingManager.h>"
after the first line
"#import "AppDelegate.h"" in the AppDelegate.m file.
If you are using React Native and the command line, Sébastien's modification proposal is to be made to ios/<yourproject>.xcodeproj/project.pbxproj by adding
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS",
to the HEADER_SEARCH_PATHS lists (4 locations)
Oh man. similar to this answer:
Anyone who is facing this issue for a react-native archive for ios
platform just place
#import <React/RCTLinkingManager.h>" after the first line
"#import "AppDelegate.h"" in the AppDelegate.m file.
I had to put it above this line (for react-native#0.70)
#if RCT_NEW_ARCH_ENABLED

Compile importing file when file being imported changes?

So if I have an aggregate file with imports in it:
#import "global"
#import "menus"
#import "datepicker"
#import "index"
#import "drawers"
Is there a way to have that file compile when any of the things it is importing change?
Yes can make it possible with grunt
http://gruntjs.com/
Here is complete workflow of grunt + compass
http://matthew-jackson.com/notes/development/grunt-workflow-for-sass-compass-and-js/

Resources