Objective-C using a class without creating multiple instances [duplicate] - swift

I have been mixing Swift and Objective C just fine but I'm having issues gaining access to a Swift class from the HEADER file of Objective C. I can do so successfully in the .m file.
Within the .h file I import the Xcode generated file that has the format "Appname-Swift.h". However, in doing so I get the message that the file is not found. I can do this same import in my .m file with no issue. However, I need it in the .h file as I reference a Swift class that I need access to with public API.
How can I make use of the Swift class from the .h portion of Objective C?
Example:
#import <UIKit/UIKit.h>
#import "MyApp-Swift.h"
#interface SelectedContactsVC : UIViewController
#property (nonatomic,strong) MapVC *mapVC;
#end
MapVC above is a Swift class.

Move #import "MyApp-Swift.h" to .m file.
And make your .h file as:
#import <UIKit/UIKit.h>
#class MapVC;
#interface SelectedContactsVC : UIViewController
#property (nonatomic,strong) MapVC *mapVC;
#end
Swift cannot generate "MyApp-Swift.h", if it's imported from Objective-C header, sort of mutual dependency thing maybe.

Related

Duplicate symbol _OBJC_METACLASS_$_SBJsonParser

I just included AWSIOSSDK.framework and Facebook SDK together in my project, then got a build error:
ld: duplicate symbol _OBJC_METACLASS_$_SBJsonParser in /Users/tom8/Desktop/site1/site1/facebook-ios-sdk/libfacebook_ios_sdk.a(SBJsonParser.o) and /Users/tom8/Desktop/AWSiOSSDK.framework/AWSiOSSDK(SBJsonParser.o) for architecture i386
I use iOS Facebook SDK Static Library, so i could not simply delete sbjson files in facebooksdk folder. I also tried to delete sbjson files in AWSIOSSDK folder, but it also did not work. Could someone give me some advice?
Almost without exception, when I get duplicate symbol build errors, it's because I was #include-ing .h files too prolifically from other .h files. The solution is almost always these two simple steps:
move as many #include directives into .m files as possible
use #protocol and #class forward-declarations in .h files.
The only cases where you need to #include an .h from an .h is when you actually extend a class or implement a protocol. If you just need to use a class name or protocol name in a signature, use forward declarations and move the #include to the .m file.
Example:
foo.h
#include "Bar.h"
#include "BazProtocol.h"
#include "BarDelegateProtocol.h"
#interface Foo:NSObject <BarDelegate>
#property (strong, nonatomic) id<Baz> myBaz;
#property (strong, nonatomic) Bar *myBar;
#end
becomes
#include "BarDelegateProtocol.h"
#class Bar;
#protocol Baz;
#interface Foo:NSObject
#property (strong, nonatomic) id<Baz> myBaz;
#property (strong, nonatomic) Bar *myBar;
#end
I had the same problem too. You can delete the files from the Facebook Project itself, but you cannot delete from the framework.
So click:
facebook-ios-sdk.xcodeproj (to open up file contents) -> FBConnect (to view folder contents) -> JSON (to view folder contents) -> remove SBJsonWriter and SBJsonParser.
Try compiling. You should be good to go!
Eva

where i define variable ( 15 to 20 variable) .. Appdelegate File, or .PCH File or define them extern

i have 15 to 20 Variable i wants access it in my whole project. what is the best place for defining it and why?.. Appdelegate File, .Pch file or define these Extern.
really thanks in Advance.
Accessing your app delegate from various points of your app creates a strong coupling between these components of your app.
Basically you are using globals through your app which is usually a good indication for an improvable application design.
Variables usually do not live in thin air. They exist in a context. For example if you are using username and password you should get them from the system's keychain. The whole authentification process should be wrapped in an authentification class in which you would define the properties.
If you need to access information from various places of your app, you have to pass them as arguments of the initializer for example. This btw renders your individual components testable which is a good thing.
My advice is to rethink your app design first to not end in dependency hell later on.
You can define them as properties in your AppDelegate class. For example:
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (retain, nonatomic) NSString *publicString;
If you want to make them readonly for external objects then you can define as follows:
1) in AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (retain, readonly, nonatomic) NSString *publicString;
2) in AppDelegate.m
#interface AppDelegate ()
#property (retain, readwrite, nonatomic) NSString *publicString;
#end
#implementation AppDelegate
#synthesize publicString;
// other methods below
#end
Create one header file by name 'defines.h' and implement all defines and constants in it.
import this file in .Pch file
This is the best one, and will be separate from other classes.

Import directive not giving access to the class

I am including a file like this:
#import "BannerPhoneContentController.h"
however, when I try to use it like this:
bannerContentController = [[BannerPhoneContentController alloc] init];
I get the error:
Use of undeclared identifier 'BannerPhoneContentController';
what could be causing the code to seemingly ignore my import?
this is the header for banner content controller.
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "BannerContentController.h"
#interface BannerPhoneContentController : BannerContentController <UIScrollViewDelegate>
{
UIScrollView *scrollView;
UIPageControl *pageControl;
NSMutableArray *viewControllers;
// To be used when scrolls originate from the UIPageControl
BOOL pageControlUsed;
}
#property (nonatomic, retain) UIScrollView *scrollView;
#property (nonatomic, retain) UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *viewControllers;
- (IBAction)changePage:(id)sender;
#end
EDIT bannerContentController is of type BannerContentController NOT BannerPhoneContentController. The latter is a subtype of the former. It is definitely worth noting that this exact code works just fine in another app, so it's nothing to do with the code itself - just how it's being included apparently. I'm stumped.
EDIT ok found the problem - not sure how to fix it. I generated the preprocessed file and the header file it's included is in fact this:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "ContentController.h"
#interface PhoneContentController : ContentController <UIScrollViewDelegate>
{
UIScrollView *scrollView;
UIPageControl *pageControl;
NSMutableArray *viewControllers;
// To be used when scrolls originate from the UIPageControl
BOOL pageControlUsed;
}
#property (nonatomic, retain) UIScrollView *scrollView;
#property (nonatomic, retain) UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *viewControllers;
- (IBAction)changePage:(id)sender;
#end
note the difference - all the 'Banner's are missing. This is what the file used to look like. However, I've checked and the file that's in the project is the one I posted at the top. I tried cleaning the solution and building again. How can I fix this and why has it happened?
EDIT The file that I'm including all this in is part of a code library. I have now created a new project, imported the code library and included all of this in that library once again in exactly the same way. and it works. I have looked over the two projects and the code in question is identical. This must be a project setting?
It looks for me like recursive import. Say, BannerContentController.h imports BannerPhoneContentController.h, and BannerPhoneContentController.h imports BannerContentController.h.
If it is the case, then you should resolve recursive dependencies. E.g. using forward declaration.
does using #class BannerPhoneContentController in .h and #import "BannerPhoneContentController.h" in .m gives the same result ?
After a lot of messing around, and thanks to a comment from Yuras I generated the preprocessed code and realised the problem was that the OLD version of the code was being included.
More useful is WHY. It's just a bug in XCode that happens sometimes when incremental linking is turned on - basically this is where time is saved by only changing the parts of the pre-processed file when the corresponding bits of your code have been altered. Unfortunately, this does not alway work correctly.
The solution, annoyingly, was to delete the files, clean the build, delete the derived data (window / oraniser / projects / project name / delete derived data), restart xcode (possibly also restart your computer, or throw it out of the window and buy a new one) then re-import the files.
XCode can be a real pain...

Xcode: very strange error subclassing my own class

I have an iPhone app with a custom class, Detail, a subclass of UIViewController that I created.
I need to make a subclass of Detail, and I want to to call it ActivityDetail. So I wrote the following in my ActivityDetail.h file:
#import <UIKit/UIKit.h>
#import "Detail.h"
#interface ActivityDetail : Detail {
}
#end
The problem is that I'm getting a compiler error telling me this:
error: cannot find interface
declaration for 'Detail', superclass
of 'ActivityDetail'
And the strange thing is: I can change the superclass from Detail to UIView (for example), compile getting many errors (obviously), and then change the superclass to Detail again and everything works fine! But if I then change anything to the Detail class the problem comes back from the beginning...
How can I solve this?
It is recommended to not import classes beyond the default Foundation or UIKit imports in your header files. Instead you should do something similar:
Header
#import <UIKit/UIKit.h>
#class Detail;
#interface ActivityDetail : Detail {
}
#end
Implementation
#import "ActivityDetail.h"
#import "Detail.h"
#implementation ActivityDetail
#end
This allows your header to "know" about additional classes without forcing all "importers" of that header to also import everything it imports.
Here is a great reference question, and a great answer, regarding the usage of #class and #import.
Erm you are importing Detail as Dettaglio.h. Probably the compiler is not fluent in Italian.
Are you importing the .h where Detail is declared?
#import "Detail.h"
Either #import "Detail.h" or subclass from Dettaglio (depends on whichever one your Detail class is actually named.

Unable to build project with CoreData classes

I am trying to migrate my sandpit code into my main project but for some reason I am getting the following strange error when trying to compile
syntax error before 'NSManagedObjectModel'
At first I thought this was because coredata wasnt in the prefix.pch file but I have added it in there too.
This is the top of AppDelegate where the code is being used (straight out of an Apple example)
#import <UIKit/UIKit.h>
#import "AppSettings.h"
#import "Skin.h"
#interface JeanieAppDelegate : NSObject <UIApplicationDelegate> {
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
#import <CoreData/CoreData.h> and don't forget to link it in.
Also, beware adding just anything to your .pch file. When you do so, those header files will be included all throughout your projectYou should only really put things there that are truly going to be universally required all through your project.