Why can I import nothing in .m file - objective-c

Edit:
I finally found out that I import a header file which has indirect import for the JSONModel.h file.
Today I tried AppCode and it gives me some hint that some import is useless.
I found out that it seems that some subclasses of [JSONModel][1] can omit import statement of its own header file in the implementation file (.m file) and compile successfully.
For example:
TestModel.h
#import "JSONModel.h"
#interface TestModel : JSONModel
+ (JSONKeyMapper *)keyMapperWithJsonToModelDic:(NSDictionary *)jsonToModelDic;
#end
TestModel.m
#implementation TestModel
+ (JSONKeyMapper *)keyMapperWithJsonToModelDic:(NSDictionary *)jsonToModelDic {
return jsonToModelDic;
}
#end
So when can I omit the import statement?
Thanks.

Because of the Prefix header file (ProjectName-Prefix.pch) which contains the necessary system header files and is applied to all implementation files by Xcode.

Related

Set up interface definitions for a category, if methods of the category are called from another class

Let’s say I have a class Alpha , and a category Alpha+morefeatures with a method -(void)foo. Another class , say Beta, should call the method foo.
I like to use the categories for splitting the code into parts, so that Alpha.m will not be a big file.Where should I put the includes & interface description then?
I tried:
file Alpha.h——————————
#interface Alpha {
...
}
-(void) foo;
file Alpha.m——————————
#import „Alpha.h“
file Alpha+morefeatures.h --------------
#import "Beta.h"
#interface Alpha (morefeatures)
file Alpha+morefeatures.m --------------
#import Alpha+morefeatures.h
#implementation Alpha (morefeatures)
-(void)foo {
...
}
file Beta.h——————————-
#import „Alpha.h“
Alpha+morefeatures.h is not imported anywhere else than in Alpha+morefeatures.m . This compiles ( and runs well) but it gives the following compiler warnings:
“Category is implementing a method which will also be implemented by its primary class”
"Method definition not found"
How can I get rid of the warnings ? I have seen some answers which deal with compiler options - but I assume it is more a syntax problem.
Any advise is appreciated.
I found a way , finally: All I have to do is to add the interface description into Alpha.h
#interface Alpha (morefeatures)
-(void)foo;
#end
Then import Alpha.h in Beta.h

Creating Dynamic Framework Xcode

I am trying to create a dynamic framework project, I can use to inject code and for reverse engineering purposes.
I've been successfully able to inject code using Objective C file "(.m)" file.
#import <Foundation/Foundation.h>
#import "CodeInjection-Swift.h" // This line gives error.
#interface CodeInjection: NSObject
#end
#implementation CodeInjection
static void __attribute__((constructor)) initialize(void){
NSLog(#"==== Code Injection in Action lolz====");
[[CodeInjectionSwift shared] performTask];
}
#end
I also have a file called "CodeInjectionSwift.swift"
import Foundation
import NetworkInterceptor
#objc class CodeInjectionSwift: NSObject {
#objc public static let shared = CodeInjectionSwift()
override private init(){}
#objc func performTask(){
let requestSniffers: [RequestSniffer] = [
RequestSniffer(requestEvaluator: AnyHttpRequestEvaluator(), handlers: [
SniffableRequestHandlerRegistrable.console(logginMode: .nslog).requestHandler()
])
]
let requestRedirectors: [RequestRedirector] = [
RequestRedirector(requestEvaluator: DomainHttpRequestEvaluator(domain: "www.antennahouse.com"), redirectableRequestHandler: AlternateUrlRequestRedirector(url: URL(string: "https://www.rhodeshouse.ox.ac.uk/media/1002/sample-pdf-file.pdf")!))
]
let networkConfig = NetworkInterceptorConfig(requestSniffers: requestSniffers,
requestRedirectors: requestRedirectors)
NetworkInterceptor.shared.setup(config: networkConfig)
NetworkInterceptor.shared.startRecording()
}
}
If I get rid of the #import "CodeInjection-Swift.h" and the line [[CodeInjectionSwift shared] performTask];
The NSLog prints and am able to build successfully. I was told that I have to import -Swift.h file to use swift classes in CondeInjection-swift.h
Error message is
"-Swift.h not found"
My goal is to build the framework, and be able to utilize "CodeInjectionSwift" functionality that uses import NetworkInterceptor

Can I prevent extensions from being exported to Swift header for Objective-C?

I have an Objective-C project with 1 Swift class. This class is using a framework that is also written in Swift. (Used CocoaPods to include the framework)
My problem is that the -Swift.h file is exporting my extensions that adhere to protocols in the framework. Now when I try to import the -Swift.h file in the Objective-C, it complains that that the protocol definitions cannot be found.
I don't want these extensions exported. They are only used in this class. I can't use private or fileprivate for extensions that declare protocol conformances. I also tried adding #nonobjc before the extension declaration (which cascaded warnings into my methods) and it was still exported.
Here are my extensions:
extension MessagingExperience: MessagingDelegate {
...
}
extension MessagingExperience: MessagingNotificationDelegate {
...
}
And generated header:
#interface MessagingExperience (SWIFT_EXTENSION(Reference_App)) <MessagingDelegate>
- (void)MessagingObseleteVersion:(NSError * _Nonnull)error;
- (void)MessagingError:(NSError * _Nonnull)error;
#end
#interface MessagingExperience (SWIFT_EXTENSION(Reference_App)) <MessagingNotificationDelegate>
- (BOOL)shouldShowMessagingNotificationWithNotification:(MessagingNotification * _Nonnull)notification SWIFT_WARN_UNUSED_RESULT;
- (void)messagingNotificationTapped:(MessagingNotification * _Nonnull)notification;
- (UIView * _Nonnull)customMessagingNotificationViewWithNotification:(MessagingNotification * _Nonnull)notification SWIFT_WARN_UNUSED_RESULT;
#end
Errors produced by including the -Swift.h in an Objective-C class:
Cannot find protocol declaration for 'MessagingDelegate'
Cannot find protocol declaration for 'MessagingNotificationDelegate'
Is there a way to prevent this from being in the header?
Thanks.
Create a private class in MessagingExperience.swift that conforms to the protocol defined in the framework. Because it's a private class, the protocol won't be specified in the generated -Swift.h.

Accessing Objective-C variables/functions from Swift

Suppose I have a connector named Connector.m (written in Objective-C). And I would like to create a new connector written using Swift, named Connector.swift. I would like to access all of the variables and methods from Swift. I have create a bridging-header and write import of the header file of the Connector. But I can't access any of global variables on the Objective-C class.
Connector.m
NSString * const kHTTP_METHOD_GET = #"GET";
Connector.swift
public class Connector: NSObject {
var parentConnector : Connector
override init() {
self.parentConnector = Connector
}
func test() {
print(parentConnector.kHTTP_METHOD_GET) //--> ERROR : Value of type 'Connector' has no member 'kHTTP_METHOD_GET'
}
}
Is it possible to do this? Thanks.
Make sure you have header file like this...
{project-name}-Bridging-Header.h
Add your class file in Bridging-Header.h
#import "Connector.h"
And Put your below code in Connector.h file..Because in Bridging-Header.h will only import header file
NSString * const kHTTP_METHOD_GET = #"GET";
to on top of #interface scope..
Add following line in Connector.h.
extern NSString * const kHTTP_METHOD_GET;
Include Connector.h to your bridging header file.
I believe the methods/variables in Connector.m also need to be public for it to work.
This sounds like a good use-case for the Adapter Pattern. But you should be able to access Objective-C code easily.
Make sure your bridging header file is named like this:
{your-project-name}-Bridging-Header.h
Inside your bridging header add the following:
#import "Connector.m"
Then you have to make sure the compiler knows about your bridging header:
Click your root project > Select your target app > Build Settings
Then scroll down until you see this:
Make sure your bridging header is listed, build and you should have access to your Objective-C code.

Less CSS : Conditional #imports using mixins - Variable scope

What I'm attempting to do is #import specific files into my Less project by setting checking for specific variables. This is what I have so far:
#import "shared/variables";
#import "shared/global";
#import "shared/hero";
#import "shared/listings";
//
// Color Variations
// Based on #bt-color-variation
// Decides when to load the light/dark theme
//
#bt-color-variation: dark; // Default color variation
.bt-color-variation(dark) {
#import "color-variations/dark/global";
#import "color-variations/dark/variables";
}
.bt-color-variation(dark) {
#import "color-variations/light/global";
#import "color-variations/light/buttons.less";
#import "color-variations/light/variables";
}
.bt-color-variation(#bt-color-variation);
This does in-fact load the appropriate color variations based on that variable. The issue is that any variables set within that color variation's variable.less file are not overriding what is done outside of it in the shared/variables.less file. It seems like there's an issue with either "when" mixins are run compared to the regular #imports or a scope issue. I was hoping the mixins would run after and use Less's "last-win" case for variables.
Any ideas with how I'd conditionally load files based on a Less variable (and not deal with variable scope) would be EXTREMELY helpful. Thanks as always.
Variables from within mixins do not override those in the caller scope (see Mixins as Functions).
For this use-case I'd suggest something more simple:
#bt-color-variation: dark;
#import "color-variations/#{bt-color-variation}/global";
#import "color-variations/#{bt-color-variation}/buttons";
#import "color-variations/#{bt-color-variation}/variables";
See Variabes > Import statements.