Call objective C macro from swift - objective-c

I have created a CLogger objective C class and defined below macro
#define CLogError(fmt, ...) //remaining code
I am able to access CLogError in objective C files and call it. But above macro is not accessible in swift file. How can I call this from swift?

You can't, at the moment. You can always define it in Swift as a global function:
func CLogError(fmt : String, strings : String...) { ... }

Related

Updating Bridging-Header File

I've got an Objective C project and I'm trying to use Swift file in it. I've added swift file and Xcode automatically created Bridging Header. So I could create an object of my swift class in obj-c file and access to its properties. But then I added a new string to my swift file. And I can’t access a new-added property from my objective C file. So I think, I have to update or recreate Bridging Header, haven't I? Can anybody help me?
Did you put #objc in front of your class or property? like:
#objc public class myClass {
#objc var str: String = "str"
}

How to use NSData+Base64Additions.h Objective C class in Swift?

I need use a function from Objective C in Swift class
-(NSString *)encodeBase64ForData{}
In Objective C I call with this form:
#import "NSData+Base64Additions.h"
[videoPath encodeWrappedBase64ForData]
But in Swift, i can't import this class. How can use this encoder?
Thanks!
First hit on google: http://ios-blog.co.uk/tutorials/quick-tips/base64-decoding-in-ios-7-objective-c-and-ios8-swift/
Basically, you don't need to import the category for NSString. You can use the builtin functionality for base64 strings.
let plainString = "my string to encode"
let plainData = (plainString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let base64String = plainData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromRaw(0)!)
println(base64String) // Something like bXkgc3RyaW5nIHRvIGVuY29kZQ==
You need to use the objective-c bridging header file, and add that import into it. The first time you create an objective c class in a swift project it should prompt you to create, otherwise you have to manually create and set it in your build settings "Objective-C Bridging Header".
More info can be found at:
https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/MixandMatch.html

How to use a Objective-C #define from Swift

I am migrating a UIViewController class to train a bit with Swift. I am successfully using Objective-C code via the bridging header but I have the need of importing a constants file that contains #define directives.
I have seen in Using Swift with Cocoa and Objective-C (Simple macros) the following:
Simple Macros
Where you typically used the #define directive to define a primitive constant in C and Objective-C, in Swift you use a global constant instead. For example, the constant definition #define FADE_ANIMATION_DURATION 0.35 can be better expressed in Swift with let FADE_ANIMATION_DURATION = 0.35. Because simple constant-like macros map directly to Swift global variables, the compiler automatically imports simple macros defined in C and Objective-C source files.
So, it seems it's possible. I have imported the file containing my constants into the bridging header, but I have no visibility from my .swift file, cannot be resolved.
What should I do to make my constants visible to Swift?
UPDATE:
It seems working with NSString constants, but not with booleans:
#define kSTRING_CONSTANT #"a_string_constant" // resolved from swift
#define kBOOL_CONSTANT YES // unresolved from swift
At the moment, some #defines are converted and some aren't. More specifically:
#define A 1
...becomes:
var A: CInt { get }
Or:
#define B #"b"
...becomes:
var B: String { get }
Unfortunately, YES and NO aren't recognized and converted on the fly by the Swift compiler.
I suggest you convert your #defines to actual constants, which is better than #defines anyway.
.h:
extern NSString* const kSTRING_CONSTANT;
extern const BOOL kBOOL_CONSTANT;
.m
NSString* const kSTRING_CONSTANT = #"a_string_constant";
const BOOL kBOOL_CONSTANT = YES;
And then Swift will see:
var kSTRING_CONSTANT: NSString!
var kBOOL_CONSTANT: ObjCBool
Another option would be to change your BOOL defines to
#define kBOOL_CONSTANT 1
Faster. But not as good as actual constants.
Just a quick clarification on a few things from above.
Swift Constant are expressed using the keywordlet
For Example:
let kStringConstant:String = "a_string_constant"
Also, only in a protocol definition can you use { get }, example:
protocol MyExampleProtocol {
var B:String { get }
}
In swift you can declare an enum, variable or function outside of any class or function and it will be available in all your classes (globally)(without the need to import a specific file).
import Foundation
import MapKit
let kStringConstant:String = "monitoredRegions"
class UserLocationData : NSObject {
class func getAllMonitoredRegions()->[String]{
defaults.dictionaryForKey(kStringConstant)
}
simple swift language don't need an macros
all #define directives.
will be let
and complex macros should convert to be func
The alternative for macro can be global variable . We can declare global variable outside the class and access those without using class. Please find example below
import Foundation
let BASE_URL = "www.google.com"
class test {
}

Pass by reference in objective c

I am a calling c++ method from objective c:
C++ Method:
void TestMethod( size_t& outputSize,
OutputArray& outputArray );
Objective C:
-(void) testMethodObjc : outputSize,
OutputArrayObjc : outputArray
{
TestMethod( outputSize, [outputArray getArray ]);
}
How do I accomplish this? I hear from other postings that objective-c does not support pass by reference.
You should be able to - Obj-C is a strict subset of C. Just make sure that the file the code is in is a .mm file - not just .m
Objective-C, like C, does not support pass by reference.
Like C, you can take the address of the variable and pass a pointer instead. And to manipulated the original variable in the function you would need to dereference the pointer.

Objective c wrapper for a c file

I went through quite a number of websites, but everywhere they have given how to write a wrapper for a c++ library.
Now, I have a .c file which i want to integrate to my application. Since Objective c is an objected oriented extension of c, will i actually have to write wrapper for it? if yes, how to do it? if i dont have to, then how to use the c code in my project?
EDIT : ok.. what i have to do is add the file into my project and use the functions? how exactly to do it?? just like normal c call? what if i have to pass parameters?
Let say i have a function which returns a string, first of all how do i call that function? and if it returns a string, can i store that value in a normal NSString?? or should i declare a c string for it??
Thanks in advance
You can simply use your C code as usual:
-(void)writeString:(NSString*)data toFile:(NSString*)filename {
FILE* output = fopen([filename UTF8String], "w");
fprintf(output, "%s", [data UTF8String]);
fclose(output);
}
For other .c files, simply #include the corresponding header. Then, you can just call its functions.
For example, if this was foo.h:
int add(int a, int b);
And foo.c:
#include "foo.h"
int add(int a, int b) {
return a + b;
}
Then in your Objective-C code (Bar.m):
-(int)addA:(int)a andB:(int)b {
return add(a, b);
}
That is basically a wrapper right there. However, wrappers are not needed for C code in Objective-C. Even C++ functions do not need wrappers, as there are .mm files which are Objective-C++ sources.
Edit:
To call C functions with parameters, just call them with parameters. Literally ANY valid C program is also a valid Objective-C program. If it can compile as a .c file, it'll compile as a .m file.
To convert a C string (char*) to an NSString:
const char* myString = "Hello!";
NSString* myNSString = [NSString stringWithUTF8String:myString];