In AFNetworking, what does #ifdef _SYSTEMCONFIGURATION_H mean? - ios

This check is in my AFHTTPClient.m file. The check is actually used very frequently throughout the file and the .h file. In one case, it does this:
#ifdef _SYSTEMCONFIGURATION_H
self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;
[self startMonitoringNetworkReachability];
#endif
This is still version 1.X of AFNetworking.
Thanks!

I believe this is a pre-processor statement checking that you have linked your project with the SystemConfiguration framework. If not, I believe that AFNetworking was omitting some feature, or maybe it was giving you a nice warning to make sure you don't forget to include this framework, so that AFNetworking could work as expected.
Update
#ifdef _SYSTEMCONFIGURATION_H
#import <netinet/in.h>
#import <netinet6/in6.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h>
#endif
So what's going on is if _SYSTEMCONFIGURATION_H is defined (internally by the SystemConfiguration framework), then AFNetworking knows that you included this framework in your project, and so it is importing a bunch of things to make use of it. Otherwise it isn't. This means that you don't have to include this framework if you don't want to.

To solve this problem, type
#import <SystemConfiguration/SystemConfiguration.h>
#import <MobileCoreServices/MobileCoreServices.h>
before importing AFNetworking.

Related

Xcode generated umbrella header for framework does not import Foundation when #objc inference is turned off

I have a framework written entirely in Swift, and it's included in an app that uses a mix of Objective-C and Swift, i.e.
#import "MyFramework-Swift.h"
If Swift 3 #objc inference is turned ON for the framework target then everything compiles and runs fine. If Swift 3 #objc inference is turned OFF then the framework itself will compile, but the file that it's included in does not and spits out a bunch of errors like:
Unknown type name 'NSArray' or Unknown type name 'NSError'
The imports in the Objective-C file where I'm trying to use this framework essentially look like this (i.e. Foundation is being imported before trying to import the swift framework):
#import Foundation;
#import <OtherNonSystemHeaders.h>
#import "ThisFilesHeader.h"
#import "MyFramework-Swift.h"
If I open up the header file that Xcode generates there's a section about 150 lines down that looks like this:
#if __has_feature(modules)
#import ObjectiveC;
#endif
And if I manually change it to this it will compile and run.
#if __has_feature(modules)
#import ObjectiveC;
#import Foundation;
#endif
Obviously that's not a real solution since it gets overwritten any time Xcode regenerates that header, but I can't understand why turning off #objc inference is causing that import to disappear. I have manually marked certain methods as #objc, all the classes in the framework subclass NSObject, and each file imports Foundation.
I thought this might be a bug, but this happens both with Xcode 9.2 and 9.3, and clearly people are able to turn off #objc inference since it's now a recommended setting. But I am truly at a loss.
This sounds like you're missing #import Foundation; in your ObjC prior to:
#import "MyFramework-Swift.h"
ObjC files should #import Foundation; themselves. This is often also placed in the precompiled header (.pch) for performance reasons, but each .m should still import everything it needs, including Foundation.
Typically I recommend the following layout for .m files:
#import ...System Headers...
#import "Non-system framework headers"
#import "Local headers"
#import "Project-Swift.h"
We recently had to workaround what sounds like the same problem, although for us #objc inference didn't make a difference. Here is what we did:
In the MyFramework project, add a top-level header file MyFramework.h with just this one-liner:
#import Foundation;
Make sure that this file is added to each of the targets in your framework project as a Public header (not Private or Project... this part is important).
Rebuild the framework. The generated MyFramework-Swift.h still won't #import Foundation but you will see the new MyFramework.h file right beside it in the built framework's Headers folder.
Import your framework into your app's Objective-C files using the same #import <MyFramework/MyFramework-Swift.h> syntax you're probably already using. You should no longer receive the Unknown type name errors.

use of #import when modules are disabled

I have a problem
#import Foundation;
and I see:
#import vs #import - iOS 7
and I set "Enable Modules" to "YES"
and my problem is not solved
I got this warning in a zero-swift project whenever I tried to add the #import SafariServices; statement.
Solution:
Enable the modules. Go to the Target > Build Settings and set the Enable Modules (C and Objective-C modules) to YES.
OR
Note: I haven't verified this potential solution, but probably worthy of consideration if there are side effects caused by this solution.
Rather than enabling modules to entire project, we can enable modules for a specific file which is importing c++ file. Go to build phases -> Compile Sources -> Select the file -> Add compiler flag -fmodules
The possible cause is that you use Objective-C++. Then modules get disabled despite the proper build settings.
I've been mixing ObjC, ObjC++, C++, and Metal. Whenever I get the "use of #import when modules are disabled" I try
replacing:
#import Name;
with:
#import "Name/Name.h"
example, replace:
#import Metal;
#import MetalKit;
#import CoreVideo;
with:
#import "Metal/Metal.h"
#import "MetalKit/MetalKit.h"
#import "CoreVideo/CoreVideo.h"
It seems to work.
Check if you are using #import "ProductName-Swift.h" somewhere in .mm files or any other files other than objc files.
Because if you use this import in cpp files then modules gets disabled automatically.

Conditional compiling of Objective-C in a Swift project

I have an Objective-C category that I've been using for a while for both iOS and OSX projects and I want to use it in a Swift project as-is...until I have the time to translate it to Swift.
Here's the top of my category's .h file:
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#else
#import <Cocoa/Cocoa.h>
#endif
I've included it in the bridging header, but when I build the project for iOS, I get an error saying that it can't find the file Cocoa/Cocoa.h.
Why is it even looking for it? Doesn't the conditional compile still work even in a Swift project? It's still compiling an Objective-C file.
Thanks.
Add #import "TargetConditionals.h" in your source file.
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#else
#import <Cocoa/Cocoa.h>
#endif
Or add "-DTARGET_OS_IPHONE" to the "Other C Flags" section of the target build options.

Importing Core Data to existing project fails

I have a workspace and I'm trying to add Core Data to it. I went to the project I want to add Core Data to, selected the Target, hit the + sign under Link Wit Binary Files and added the Core Data framework. That part works fine. I can build and run. When I try the next and using this line:
#import <CoreData/CoreData.h>
I get build errors. These build errors look like:
"ARC Semantic Issue"
Pointer to non-const type 'id' with no explicit ownership
These errors are present in
NSEntityDescription.h
NSManagedObjectModel.h
NSMnagedObject.h
NSManagedObjectContext.h
NSPersistentStore.h
Does anyone know why I'm not able to import Core Data to an existing iOS project? Thanks in advance!
In my framework search paths, I had an erroneous path that correctly built once I removed it:
$(DEVELOPER_DIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks
It should be as simple as adding CoreData.framework to your target:
Click the plus button (+) under Linked Frameworks and Libraries
Then in your Prefix file (Tabs-Prefix.pch in this case) in the #ifdef __OBJC__ declaration:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#impport <CoreData/CoreData.h> //Added core data here
#endif
If this does not work, perhaps you have an older version of Xcode installed and the paths are messed up. It could be trying to import an older framework.
I think this could be related to your entity definitions. Is it possible that you have declared entities that use the attribute name id? That would typically be a NSNumber type in the model subclasses, i.e. *id.
It seems that in this case, the compiler instead of complaining about the *id in the class files, it indicates the id in the header files, which is confusing.
--> Try changing your attribute names.
I had the same problem. It was solved by the following steps:
Remove Reference to CoreData.framework from Frameworks group in Xcode.
Remove CoreData.framework from 'Link Binary with Libraries' in target settings.
Quit Xcode (Cmd + Q).
Open your project folder in Finder and delete CoreData.framework file.
Start Xcode, open your project. Now you may to add the CoreData.framework in 'Link Binary with Libraries'.
Don't forget to add #import <CoreData/CoreData.h> into <projectName>-Prefix.pch located at Supported Files. My prefix header seems like this:
`
#import <Availability.h>
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#endif
`
I don't know how existance of any file in project directory can affect to compile errors, but it works for me.
Hope this helps for anyone who reads it.

Failing to import c-file in objective-c

I'm currently trying to compile my project just after adding some C code.
I'm using the Paul Kocher's blowfish algorithm implementation available on Bruce Schneier's website.
Since I included blowfish.c & blowfish.h in my workspace, my compiler is running crazy. Like if it did not recognize Objective-c code, pointing errors on NSObject class!
I tried to .mm the calling class but the problem stays.
Each answer found on SO talks about including C++ file, but it's not my pb...
Maybe a compiler directive that i'v missed ?
Most likely, what is happening is that the compilation of blowfish.c is using your previously established precompiled header (.pch) file, and that is including an Objective-C framework. Just disable the precompiled header and you should be OK. You might be able to conditionalize those frameworks, but personally, I find precompiled headers more trouble than they’re worth.
Thanks to microtherion, I found the problem.
My .pch file was declared as :
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
#import "AppDelegate.h"
#import "UINavigationController+Rotation.h"
#import "Categories.h"
The 3 last #import'ed files are objective-C.
I've just changed the #endif place to:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "AppDelegate.h"
#import "UINavigationController+Rotation.h"
#import "Categories.h"
#endif

Resources