Can't see Swift variable/method in Objective C - ios

I am unable to see the method/variable to set myVar to true from Objective C even tough I've added the #objc and public modifiers and there is no Bool in the setMyVarTrue() method's signature.
This is probably caused by the difference between Swift's Bool and Objective C's BOOL.
Other class methods/variables are visible, just this particular one isn’t.
How is is possible to set Swift's Bool from Objective C?
Swift code:
public class MyViewController : UIViewController {
public var myVar:Bool = false
#objc public func setMyVarTrue() {
self.myVar = true
}
}
Objective C code:
MyViewController* myViewController = [MyViewController new];
myViewController.myVar = true // Variable not found
myViewController.setMyVarTrue() // Method not found
[self presentViewController:myViewController animated:NO completion:nil];

You should do
add #objc to declaration of your class
add a file named "yourName-swift.h", which should containt #class yourClass;
import "yourName-swift.h" in Objective C file, where you want to call
your swift class

The solution was to clean and rebuild the project. Xcode generates the swift bridging header automatically and in my case it was stopping the build process with a (variable/method not found) error prior to regenerating the bridging header.
SWIFT_CLASS("_TtC11MyProject25MyViewController")
#interface MyViewController : UIViewController
#property (nonatomic, strong) MBProgressHUD * _Nonnull progressIndicator;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
- (void)viewDidLoad;
- (void)viewWillAppear:(BOOL)animated;
- (void)submitProgressHandler:(NSNotification * _Nonnull)notification;
- (void)submitSuccessHandler;
- (void)submitFailureHandler:(NSNotification * _Nonnull)notification;
- (void)subscribe;
- (void)unsubscribe;
#end
Now it works fine:
SWIFT_CLASS("_TtC11MyProject25MyViewController")
#interface MyViewController : UIViewController
#property (nonatomic, strong) MBProgressHUD * _Nonnull progressIndicator;
#property (nonatomic) BOOL closing;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
- (void)viewDidLoad;
- (void)viewWillAppear:(BOOL)animated;
- (void)setClosingTrue;
- (void)submitProgressHandler:(NSNotification * _Nonnull)notification;
- (void)submitSuccessHandler;
- (void)submitFailureHandler:(NSNotification * _Nonnull)notification;
- (void)subscribe;
- (void)unsubscribe;
#end

Related

Cannot conform to swift delegate protocol from objective-c

I'm using a swift pod in an objective C project.
I successfully access swift classes from objective-c, anyway I'm facing an issue to adopt swift protocol.
The compiler does not complain, generated bridging header seems correct.
Problem occurs at runtime when calling [self.sceneLocationView setLocationNodeTouchDelegate: self]; that results in [ARCL.SceneLocationView setLocationNodeTouchDelegate:]: unrecognized selector sent to instance.
I cannot find any solution to this issue, I spent time to search here, but still no luck to make this working.
Any help would be greatly appreciated.
Thanks
My swift and objective-c files are shown below.
SceneLocationView.swift:
#available(iOS 11.0, *)
open class SceneLocationView: ARSCNView {
...
#objc public weak var locationNodeTouchDelegate: LNTouchDelegate?
...
}
SceneLocationViewDelegate.swift :
#objc public protocol LNTouchDelegate: class {
func locationNodeTouched(node: AnnotationNode)
}
ViewController.h :
#import "ARCL-Swift.h"
#interface ViewController : UIViewController <LNTouchDelegate>{
}
#property (nonatomic, strong) SceneLocationView *sceneLocationView;
ViewController.m :
#import "ARCL-Swift.h"
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.sceneLocationView = [[SceneLocationView alloc] init];
[self.sceneLocationView run];
[self.view addSubview: self.sceneLocationView];
...
[self.sceneLocationView setLocationNodeTouchDelegate: self]; <-- ERROR HERE
}
-(void) locationNodeTouchedWithNode:(AnnotationNode *)node {
}
ARCL-Swift.h :
SWIFT_PROTOCOL("_TtP4ARCL15LNTouchDelegate_")
#protocol LNTouchDelegate
- (void)locationNodeTouchedWithNode:(AnnotationNode * _Nonnull)node;
#end
SWIFT_CLASS("_TtC4ARCL17SceneLocationView") SWIFT_AVAILABILITY(ios,introduced=11.0)
#interface SceneLocationView : ARSCNView
#property (nonatomic, weak) id <LNTouchDelegate> _Nullable locationNodeTouchDelegate;
- (nonnull instancetype)init;
- (nonnull instancetype)initWithFrame:(CGRect)frame options:(NSDictionary<NSString *, id> * _Nullable)options OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
- (void)layoutSubviews;
- (nonnull instancetype)initWithFrame:(CGRect)frame SWIFT_UNAVAILABLE;
#end

Could not build Objective c Module

i was making a xcode project with swift and it was working fine but suddenly it started giving me this error.
Could not build Objective C Module 'Foundation'
/Users/admin/Downloads/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.2.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSNotification.h:17:4: Prefix attribute must be followed by an interface or protocol
Even when i create a new project and do nothing but just build it, this error is shown. The project is not built. When i click on the error message, it leads me to this file NSNotification.h
Here are the contents of this file
/* NSNotification.h
Copyright (c) 1994-2016, Apple Inc. All rights reserved.
*/
#import <Foundation/NSObject.h>
typedef NSString *NSNotificationName NS_EXTENSIBLE_STRING_ENUM;
#class NSString, NSDictionary, NSOperationQueue;
NS_ASSUME_NONNULL_BEGIN
/**************** Notifications ****************/
#interface NSNotification : NSObject <NSCopying, NSCoding>
id#property (nullable, readonly, retain) id object;
#property (nullable, readonly, copy) NSDictionary *userInfo;
- (instancetype)initWithName:(NSNotificationName)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo NS_AVAILABLE(10_6, 4_0) NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
#end
#interface NSNotification (NSNotificationCreation)
+ (instancetype)notificationWithName:(NSNotificationName)aName object: (nullable id)anObject;
+ (instancetype)notificationWithName:(NSNotificationName)aName object: (nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
- (instancetype)init /*NSUIImagePNGRepresentation_UNAVAILABLE*/; /* do not invoke; not a valid initializer for this class */
#end
/**************** Notification Center ****************/
#interface NSNotificationCenter : NSObject {
#package
void *_impl;
void *_callback;
void *_pad[11];
}
#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)
#property (class, readonly, strong) NSNotificationCenter *defaultCenter;
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
#endif
- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(nullable NSNotificationName)aName object:(nullable id)anObject;
- (id <NSObject>)addObserverForName:(nullable NSNotificationName)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block NS_AVAILABLE(10_6, 4_0);
// The return value is retained by the system, and should be held onto by the caller in
// order to remove the observer with removeObserver: later, to stop observation.
#end
NS_ASSUME_NONNULL_END
Please help me through this. I will be very grateful for this. Thanks.
This line in NSNotification.h looks like it's been modified:
id#property (nullable, readonly, retain) id object;
Delete the id at the front of that line and try to recompile. That should fix it.

Error in the "Objective-C Generated Interface Header Name"

I've been upgrading my project to Swift2.
After resolving many errors, i got an error when i build the project.
The error is located in the Objective-V Generated Interface Header,
Xcode is printing this error Type argument 'CGColorRef' (aka 'struct CGColor *') is neither an Objective-C object nor a block type
Here is the code, the error is printed on the line between the **:
SWIFT_CLASS("_TtC519RadialGradientLayer")
#interface RadialGradientLayer : CALayer
**#property (nonatomic, copy) NSArray<CGColorRef> * __nullable colors;**
#property (nonatomic, copy) NSArray<NSNumber *> * __nullable locations;
#property (nonatomic) CGPoint center;
#property (nonatomic) CGFloat startRadius;
#property (nonatomic) CGFloat endRadius;
- (nullable instancetype)initWithCoder:(NSCoder * __nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
- (nonnull instancetype)initWithLayer:(id __nonnull)layer OBJC_DESIGNATED_INITIALIZER;
- (void)drawInContext:(CGContextRef __nonnull)ctx;
+ (BOOL)needsDisplayForKey:(NSString * __nonnull)key;
#end
I guess that is link to this class
class RadialGradientLayer: CALayer {
var colors: [CGColor]? {
didSet {
self.setNeedsDisplay()
}
}
var locations: [CGFloat]? {
didSet {
self.setNeedsDisplay()
}
}
...
}
I didn't found any answer anywhere or even a clue so here i'm.
the error is trying to tell you that you can't have an NSArray contain primitive types.
you would get a similar error if you attempted to do something like this:
#property (nonatomic, strong) NSArray <Int>* intArray;
one way to fix this would be to make your swift class hold an array of UIColor instead of CGColor.

Property 'delegate' not found in object of type exception when trying to use delegate

can't understand what's wrong in this case, so I cant use the delegate - there is an exception in self.plistManager.delegate = self; Property 'delegate' not found on object of type 'DataPlistManager *'
#import "DataManager.h"
#import "DataPlistManager.h"
#interface DataAdapter : NSObject <DataStorageManager>
#property (nonatomic,strong) DataPlistManager *plistManager;
- (void) saveFile;
#end
and its implementation
#import "DataAdapter.h"
#implementation DataAdapter
-(id) initWithDataPlistManager:(DataPlistManager *) manager
{
self = [super init];
self.plistManager = manager;
self.plistManager.delegate = self;
return self;
}
- (void) saveFile
{
[self.plistManager savePlist];
}
#end
Your DataPlistManager needs a property delegate:
#property (weak) id<DataStorageManager> delegate;
If you add #import "DataAdapter.h" in your "DataPlistManager.h" file then remove it and add it to "DataPlistManager.m" file, I don't know but some days ago i have same issue, and i solved it by using this trick :)
DataManager class contains delegate property so you should set your object as delegate of DataManager class and call method (send message) saveFile inside delegate class:
#implementation DataAdapter
- (void)someMethod) {
DataManager *dataManagerObject = [[DataManager alloc] init];
dataManagerObject.delegate = self;
}
#implementation DataManager
- (void)someDelegateMethod {
[self.delegate saveFile];
}
Are you sure you understand concept of delegation pattern?
https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html

Compiler error - iOS "expected ")" before "Question

What's wrong with the following code? Xcode 4 is saying that the two method declarations with "Question" don't compile due to an '"expected ")" before "Question"; message, as indicated in the comments in the code below. The Question class compiles and this code has been working previously. I made some changes to Questions, but backed them out to try to figure out this compile time error.
#import <Foundation/Foundation.h>
#import "Question.h"
#interface AppState : NSObject {
int chosenAnswer;
int correctAnswers;
int currentQuestionNumber;
// this will contain the hash table of question objects
NSMutableDictionary *questionHash;
}
#property (nonatomic) int chosenAnswer;
#property (nonatomic) int correctAnswers;
#property (nonatomic) int currentQuestionNumber;
#property (nonatomic, retain) NSDictionary *questionHash;
- (void) printQuestions;
- (void) printDescription;
- (void) addQuestion: (Question *) question; // <==== error
- (int) numberOfQuestions;
- (void) saveState;
- (void) resetState;
- (Question *) currentQuestion; // <===== error
#end
Here's Question.h:
#import <Foundation/Foundation.h>
#import "AppState.h"
#interface Question : NSObject {
NSString *questionTxt;
int correctAnswer;
int number;
// this will contain the hash table of questions_answer objects
NSMutableDictionary *answerHash;
}
#property (nonatomic, retain) NSString * questionTxt;
#property (nonatomic) int correctAnswer;
#property (nonatomic) int number;
#property (nonatomic, retain) NSMutableDictionary *answerHash;
-(void) addAnswer: (NSString *) answer;
- (NSMutableArray *) answerArray;
- (void) printDescription;
- (void) printAnswers;
- (NSString *) correctAnswerText;
- (Question *) currentQuestion;
#end
Circular dependency? AppState is importing Question and Question is importing AppState.
Forward-declare one of them to break the cycle, e.g. use #class Question before your AppState #interface statement, like this
#class Question;
#interface AppState : NSObject {
int chosenAnswer;
int correctAnswers;
int currentQuestionNumber;
// this will contain the hash table of question objects
NSMutableDictionary *questionHash;
}
...
Related question: #class vs. #import
When you #import "AppState.h" in Question you make a cyclic dependency.
It would be best to move #import "AppState.h" and #import "Question.h" to implementation part. In the header just leave
#class Question;
and
#class AppState;
before interface declaration.

Resources