Accessing an externed variable from objective-c in swift - ios

I have an iOS project that uses both Obj-C and Swift.
In main.m, I want to instantiate a variable to be accessed by Swift. The specific use case is to store the absolute time at main, and then measure time elapsed since main elsewhere.
Here's what my relevant files look like:
main.m
#import <UIKit/UIKit.h>
CFAbsoluteTime StartTime;
int main(int argc, char* argv[])
{
StartTime = CFAbsoluteTimeGetCurrent(); // This is what I want to access elsewhere.
#autoreleasepool {
...
}
}
myapp-Bridging-Header.h
#import "AppDelegate.h"
extern CFAbsoluteTime StartTime;
AppDelegate.h
#import <UIKit/UIKit.h>
extern CFAbsoluteTime StartTime;
#interface AppDelegate : NSObject <UIApplicationDelegate>{}
#property (nonatomic, strong) IBOutlet UIWindow* window;
// ... other irrelevant #property
#end
And then in the actual .swift file, I'm just trying to access StartTime without declaring anything (as I thought it worked since it's being externed), but I'm getting an unresolved identifier error.

Related

Unknown type name 'NSString' when I define a block

When I define my block in my .h file, there comes an issue:
Unknown type name NSString
My code is below:
typedef void(^CancelBlock)();
typedef void(^ConfirmBlck)(NSString *); // this line comes the error
#import <UIKit/UIKit.h>
#interface LMLUpspringView : UIView
#property (nonatomic, copy) CancelBlock cancelBlock;
#property (nonatomic, copy) ConfirmBlck confirmBlock;
#end
But, why is my first block ok and the second report's an error?
You define block above the #import <UIKit/UIKit.h> (in the .h file), so there did not import the NSString, you should cut the #import <UIKit/UIKit.h> above the block define.
you need to declare block as below
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef void(^ConfirmBlck)(NSString * string);
In latest versions of xcode you can simply specify
#import <Foundation/NSString.h>
any NS Foundation class can be imported as needed.
position declaration uikit import then follow:
// declare
#property(nonatomic,strong)void(^ConfirmBlck)(NSString * string);
// define
[self setConfirmBlck:^(NSString *indexpVal) { }];
// call
if (self.ConfirmBlck) {
self.ConfirmBlck(selectedVal);
}

Objective-C Class extensions

I've started learning obj-C just recently so sorry if I'm missing something obvious.
I want to access "passCode" (extension) with clpPlayerStats object, but it's impossible to do ("Property not found on object..."). Is there any simple way to fix this?
clpPlayerStats.h
#import <Foundation/Foundation.h>
#interface clpPlayerStats : NSObject
#property(nonatomic, copy) NSString* name;
#end
clpPlayerStats.m
#import "clpPlayerStats.h"
#interface clpPlayerStats()
#property (nonatomic) unsigned int passCode;
#end
#implementation clpPlayerStats
#end
main.m
#import <Foundation/Foundation.h>
#import "clpPlayerStats.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
clpPlayerStats *clapslock = [[clpPlayerStats alloc] init];
NSString *username = [NSString stringWithFormat:#"xxxPussySlayerxxx"];
clapslock.name = username;
clapslock.passCode = 12; // <------ "Property not found on object..."
}
return 0;
}
First, class names should always start with second letters.
Secondly, Class Extensions extend the #interface of the class. And, with all things C, whether or not a declaration of anything can be seen is entirely dependent on whether the compiler can see the declaration at the time of use.
So, if you want to declare something that is semi-private, then you would typically move your #interface ClpPlayerStats() extension to a Private header file; ClpPlayerStats_Private.h. Then, if you want to access the "private" API, you #import ClpPlayerStats_Private.h.
There really isn't a formal notion of privacy in Objective-C. Just visibility to the compiler.
With this code:
#interface clpPlayerStats()
#property (nonatomic) unsigned int passCode;
#end
you are declaring a private property. If you want to use passCode outside the scope of your class you have to add in the public interface:
#import <Foundation/Foundation.h>
#interface clpPlayerStats : NSObject
#property(nonatomic, copy) NSString* name;
#property (nonatomic) unsigned int passCode;
#end
and remove the interface in the .m

In objective-c project, how can I collect all parameters(constants) in one file?

I wish to collect all the needed parameters/constants, structs, and enums in one separate file, so that I can easily find and edit them later. How can I achieve this goal?
I tried to put them in a separate .m file, and add this file to the current compile target. But it did not work. My .m file is as follows
#import <Foundation/Foundation.h>
NSTimeInterval const oneDay=86400;
NSTimeInterval const oneSecond=1;
typedef enum:NSUInteger {
EventStatusPassed,
EventStatusFinished,
} EventStatus;
Thank you
Constants.h file
#interface Constants : NSObject
extern NSString* const URL;
#end
Constants.m file
#implementation Constants
NSString* const someConstant = #"abcd";
#end
and import it in the files that you need constants
#import "Constants.h"

Xcode 5.1.1 AppDelegate.h and main.m error

I created a project a few week ago and opened it today. When i left the project there were no errors and everything worked fine, but now i have three errors and don't know why.
Here my AppDelegate.h :
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
And here my main.m:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
Here the errors:
/main.m: Semantic Issue Use of undeclared identifier 'AppDelegate'
AppDelegate.h: Parse Issue Expected identifier or '('
AppDelegate.h: Parse Issue '#end' must appear in an Objective-C context

AFHTTPClient.h mysteriously wants to add #end before interface, but then rejects its own suggestion

This is driving me crazy! I even have a different project with the exact same h file that works fine yet this does not. Xcode keeps forcing me to have to put an #end (in bold) by putting it in red, then it rejects its own suggestion with the red error "#end must appear in objective c context". WHAT AM I DOING WRONG!!!!!!
#import <Foundation/Foundation.h>
#class AFHTTPRequestOperation;
#protocol AFHTTPClientOperation;
#protocol AFMultipartFormData;
#ifdef _SYSTEMCONFIGURATION_H
extern NSString * const AFNetworkingReachabilityDidChangeNotification;
#endif
#ifdef _SYSTEMCONFIGURATION_H
typedef enum {
AFNetworkReachabilityStatusUnknown = -1,
AFNetworkReachabilityStatusNotReachable = 0,
AFNetworkReachabilityStatusReachableViaWWAN = 1,
AFNetworkReachabilityStatusReachableViaWiFi = 2,
} AFNetworkReachabilityStatus;
#endif
typedef enum {
AFFormURLParameterEncoding,
AFJSONParameterEncoding,
AFPropertyListParameterEncoding,
} AFHTTPClientParameterEncoding;
extern NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding);
extern NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding encoding);
**#end** //Here it keeps trying to force me to place an #end, then gives the error "#end must appear in objective c context"
#interface AFHTTPClient : NSObject <NSCoding, NSCopying>
...
#end
Most likely you are missing and #end in a different .h file. So probably you have one file #importing the corrupted .h (missing #end) and then you #import this file. That would explain the error.

Resources