Xcode 7 - SystemConfiguration/SystemConfiguration.h file not found [duplicate] - swift2

I've been trying to modify my project to support WatchOS2 architecture.
Currently I have a networking framework that is based on AFNetworking. I've been using it with my watch app so far.
Now I'm trying to build the framework for watchos/watchsimulator platforms.
What I'm getting is
'SystemConfiguration/SystemConfiguration.h' file not found
error for some AFNetworking classes.
I know that system configuration is not one of the available system frameworks for watchOS2. And for networking apple says:
Networking
Support for network-based operations includes the following technologies:
WatchKit extensions can access the network directly using an NSURLSession object. WatchKit extensions have full access to the NSURLSession capabilities, including the ability to download files in the background. For information on how to use this class, see URL Loading System Programming Guide.
The Watch Connectivity framework supports bidirectional communication between your Watch app and iOS app. Use this framework to coordinate activities between the two apps. For more information, see Communicating with Your Companion iOS App.
I want to support both iOS and watchos for my networking sdk.
Is there a way to make this project built for watchOS platform?
Or is that mean I am only allowed to use NSURLConnection inside my watch app?

According to the AFNetworking documentation:
URL Loading The most commonly used classes in the URL loading system
allow your app to retrieve the content of a URL from the source. You
can retrieve that content in many ways, depending on your app’s
requirements. The API you choose depends on the version of OS X or iOS
your app targets and whether you wish to obtain the data as a file or
an in-memory block of data:
In iOS 7 and later or OS X v10.9 and later, NSURLSession is the preferred API for new code that performs URL requests.
If you take a look at the diagrams on that page, it indicates that AFNetworking actually uses NSURLSession in some cases. However, since the SystemConfiguration framework is not available in watchkit, you would need to remove that dependency in order to include AFNetworking in both your iOS and watchkit apps.
I'm not sure what AFNetworking uses this framework for (it is probably very important!), but if there are certain files that wouldn't need these settings in the watch app you could modify the AFNetworking source code to not include those items on the watch app:
#if os(iOS)
// Include SystemConfiguration framework
#elseif os(watchOS)
// Exclude SystemConfiguration framework
#endif

Here is a recent commit on github for AFNetworking to support watchOS.
https://github.com/AFNetworking/AFNetworking/commit/d184833fa015a783742b573cf48a3080b863a900
Looking at the changelog..
https://cocoapods.org/pods/AFNetworking#changelog
Version 2.6.0 supports watchOS...
This release now supports watchOS 2.0, which relys on target
conditionals that are only present in Xcode 7 and iOS 9/watchOS 2.0/OS
X 10.10. If you install the library using CocoaPods, AFNetworking will
define these target conditionals for on older platforms, allowing your
code to complile. If you do not use Cocoapods, you will need to add
the following code your to PCH file.

Related

How to exclude standard but unused libswift*.dylib's from macOS app bundle and reduce bundle size

When I build my simple menubar cocoa application written in Swift 4 with Xcode 9, a lot of libswift*.dylib libraries are linked/downloaded/embedded into .app bundle,into Frameworks folder as seen below:
I am only using import Cocoa and import Foundation in my project, and some #objc functions as selector to timer functions. I really don't think my very simple menubar app would need some 3D rendering Metal library functions or any SwiftOnoneSupport, so I would like them to be removed from the .app bundle. (Same libraries are also included in the helper app for launch at login feature, which makes even the helper app over 10 MB)
I would have thought Xcode would just copy whatever is neccessary by default actually. Some similar questions were asked here and here but I don't think there is a fulfilling and up-to-date answer to both.
What I have tried so far
I set ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to NO in Build Settings. It doesn't seem to have any effect.
I set LINK_WITH_STANDARD_LIBRARIES to NO in Build Settings. It ruined everything and couldn't make it build even though I tried to add some frameworks(Cocoa, Foundation) on my own under Linked Frameworks and Libraries section.
Simply put, it's not possible to exclude the standard libraries that Swift automatically includes with an app and expect it to work. Currently any application created with Swift bundles its own version of the Swift Dynamic Library. Swift doesn’t live on the OS, rather it lives within each app bundle. What this means is that any app that is using Swift 4.1 for example bundles in the Swift 4.1 Dynamic Library (containing the 4.1 ABI), and so forth.
One of the things on the Swift project roadmap is to eventually have ABI Stability. If Swift becomes ABI Stable, Swift will live within the OS and it’s ABI will be compatible with every version of Swift.
From iOS v12.2 ABI[About] Stability for iOS is on. That is why your target will not include Swift standard library[About] because it is a part of OS

How to find code targeting an SDK version of Xamarin iOS at compile time

My app is built against iOS 11 SDK but the deployment target is set to 9.3. So, the app builds but if I don't see that there's a code that use a method only available on iOS 11 (or a version above 9) and I run it on an iOS version 9 the app crashes. So, is there a way to get all the code incompatibility with a certain version of iOS?
** Edit: New answer after reading title more carefully.
Xamarin iOS does not appear to define anything automatically for the deployment target.
If you must do it at compile time, you can define your own symbols in the compiler settings. For example you can define IS_IOS_10_OR_GREATER, then just change that for different projects.
The official advice from Xamarin is to make the determination at run time since the version of iOS you're running on is what determines capabilities. You can use conditions around code using:
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
UIDevice.CurrentDevice.SystemVersion
Another option is to create an interface and have different implementations depending on the above method calls, then select which implementation accordingly. Ioc would be very useful for this.

What are Embedded Binaries in Xcode?

I'm using Alamofire in a Swift project, and part of their manual installation instructions are to add Alamofire under Embedded Binaries in the General tab for my application target.
What are Embedded Binaries?
Embedded binaries are binary files that are copied to your application bundle when you build the project. Use embedded binaries when your application relies on third-party frameworks so people can use your application without needing those frameworks installed on their machine. Embedded binaries keep users from having to manually install third-party frameworks. Your application uses the framework you embedded.
In your Alamofire example your application relies on Alamofire. If you didn't embed the Alamofire framework, nobody would be able to use your application unless they installed Alamofire manually. By embedding Alamofire with your application everyone can run your application.
"Binary" means: compiled code — as opposed to "source code", which is what you are working with when you write code as text.
They could have given you source code and let you compile it, but they didn't; they are keeping the source code secret, so they've given it all to you after compilation, so that you can't read it.
"Embedded" means: to be included inside your app bundle, by copying them into it at build time.
So, they are handing you some compiled code (frameworks) and telling you how to include them inside your app bundle. These frameworks, unlike Cocoa's frameworks, do not already exist on the device, so if you don't include them inside the app, they won't be present and your app would be unable to call into them.
Contrast this to Cocoa's frameworks. They, too, are compiled code. But they do already exist on the device. Therefore they are not embedded inside your app; they are merely linked (and, if they appeared, would appear in the next group, Linked Frameworks and Libraries).
Embedding binaries copies the entire framework to the target.
A framework is a hierarchical directory that encapsulates a dynamic
library, header files, and resources, such as storyboards, image
files, and localized strings, into a single package. Apps using
frameworks need to embed the framework in the app's bundle.
So, when you embed a framework in your app, it increases the size of your app because it is copied to you app bundle. In most of the scenarios we will be using this sections when we are using third party framework.
When we add a framework to Embedded Binaries it automatically adds that framework to Linked Frameworks and Libraries also.
Refer to apple documentation for more details: https://developer.apple.com/library/archive/technotes/tn2435/_index.html

install app on mac with shared libraries outside bundle

I am working on a Qt app with some library dependencies, for which I will have to make an installer.
From everything I read, seems like the best way is to make a bundle app with all library dependencies, and the required Qt frameworks, inside myapp.app/Contents/Frameworks
There are other applications created in parallel... that will get to be deployed on mac as well. They will have the same library dependencies and will be built using the same Qt version.
In that case it makes sense for the libraries and Qt to be installed OUTSIDE the bundle... so both (all) apps have access without having multiple copies of the same libraries.
Does that seem reasonable - and do-able with mac osx concept of bundle islands ? And how would I create such an installer that places libraries outside the app bundle ?
The simplest method of deploying Qt for OS X is to use the macdeployqt command line tool, and you have identified correctly that the normal method is to place the frameworks inside the app bundle, but multiple apps will each have copies of the frameworks.
It is reasonable to suggest moving the Qt frameworks to a separate, external location and linking to that instead. However, you will need to manage the framework carefully, especially when it comes to providing updates and be aware that if the framework is removed or altered, all your applications will fail to load. This, however is the same for any framework dependent application.
The thing to consider is where to place the framework. Normally, external frameworks reside in /Library/Frameworks, but if we all start to use that for Qt, problems may occur when your app is installed and another developer installs their app's frameworks with a different version of the libraries.
Apple defines various 'key directories' for applications and initially, the most likely location would appear to be the "Application Support Directory", but the documentation states that this is for: -
any type of file that supports the app but is not required for the app to run
This location is often used for support files, such as templates for the user to select.
If your application is to be deployed via the Apple Store, I wouldn't be surprised if it is rejected if you use this location. However, you're not using the Apple Store, then you could deploy the frameworks here.
If the Apple Store is your method of deployment, then /Library/Frameworks is probably the only place acceptable for the Qt framework to reside, with the possibility of the problems I've mentioned above.
Alternatively, consider just how many applications you're developing and is it really an issue to bundle the frameworks multiple times against the advantages that it brings, such as allowing the user to cleanly remove the application and all of its dependencies, as well as reducing problems of the framework being altered or removed accidentally?
If you choose to move them externally, you can refer to the answer to this question, which comprehensively explains how to make installer packages, after having updated your binary dependencies on the frameworks with the install_name_tool, as outlined here.

What does the "Embedded Content Contains Swift Code" build setting in Xcode 6 do?

It's a new setting under "Build Options". What does it do? I can't seem to find any documentation about it. My guess is this: Does it have to be set to YES in a mixed Objective-C/Swift app to tell Xcode to link against the Swift Runtime?
It does not need to be Yes for linking. This setting is only for when you have a pure Objective-C target that depends on a mixed-source or pure Swift target.
Description:
Enable this setting to indicate that content embedded in a target's product contains Swift code, so that the standard Swift libraries can be included in the product.
Also in the release note of Beta 7:
The build step which embeds the Swift standard libraries in a bundle now only runs for
application product types, and only if the application itself, independent of any embedded
content, contains Swift source files. When building an application that itself does not contain
Swift source files, but embeds other content like frameworks, XPC services, app extensions,
etc. that do contain Swift code, you must set the build setting "Embedded Content Contains
Swift Code" (EMBEDDED_CONTENT_CONTAINS_SWIFT). That way the Swift libraries will
be included in the application.
Regards
According to Embedding Content with Swift in Objective-C
Swift standard libraries are copied into a bundle if and only if you are building an application and this application contains Swift source files by itself
If you are building an app that does not use Swift but embeds content such as a framework that does, Xcode will not include these libraries in your app. As a result, your app will crash upon launching
To workaround this issue, set the Embedded Content Contains Swift Code (EMBEDDED_CONTENT_CONTAINS_SWIFT) build setting to YES. This build setting, which specifies whether a target's product has embedded content with Swift code, tells Xcode to embed Swift standard libraries in your app when set to YES
I don't believe that is required to have general interoperability between Swift and Objective-C. It's as simple as adding Swift code and editing the bridging header.
If you see any of the documentation about Extensions for iOS, the lingo mentions "embedded" quite a bit: embedded content, embedded frameworks, etc. Because Extensions are organized, built, and run quite differently from normal apps, I wouldn't be surprised that there's a build setting like this one pertaining to them.

Resources