I created a new embedded framework. Within the framework I created a class called "WBButton", which is a subclass of UIButton. I have set the IB_DESIGNABLE and added IBInspectable attributes to allow configuration through Interface builder, as explained here.
It works fine when I test it from within my framework (by adding a sample .xib and placing the button on the screen), but when adding the custom button to a nib located on the project which contains the framework, I get a "Build Failed" message next to the "Designables" (see below).
Also, what does "Module" mean in Interface builder?
Xcode 6 has a bug that breaks IB_DESIGNABLE classes defined in static library or framework. The same is with CocoaPods which use static library for all Pods.
It seems this is an Xcode bug
Temporary workaround:
Create an empty category/extension in the target that contains the storyboard or nib you want to use the designable view in.
Swift:
extension CustomView {
}
Objective-C:
//.h
#interface CustomView (Category)
#end
//.m
#implementation CustomView (Category)
#end
#Andy's comment above is correct answer if you use CocoaPods and your custom library is not working, you need to uncomment use_frameworks! in your Podfile and "pod install" again.
Apparently the "IB_DESIGNABLE" is not recognized by XCode if you don't do this.
Related
I've been trying to checkout CocoaPods new framework setup to get some Pods going and I'm having trouble using the Swift one's in my Objective-C project.
First things first, this is CocoaPods prerelease 0.35, you can read about how to use and install it here.
Here's my current Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'MBProgressHUD'
pod 'SLPagingViewSwift'
MBProgressHUD is a common spinning indicator, and SLPagingViewSwift is a random project I found by typing Swift into the cocoapods search. Here's the ViewController.m In my project:
#import "ViewController.h"
#import SLPagingViewSwift;
#import MBProgressHUD;
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Works just fine
MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:hud];
[hud show:YES];
// Causes Error -- Won't build
SLPagingViewSwift *sl = [[SLPagingViewSwift alloc] init];
}
#end
Here's the SLPagingViewSwift declaration:
class SLPagingViewSwift: UIViewController, UIScrollViewDelegate {
As you can see, it inherits from UIViewController, so it shouldn't be a problem to just allocate it and initialize it. If I add the file separately as just a file, the above code runs just fine. I know it works.
tl;dr
How can I use a pure Swift Framework created by CocoaPods in a pure Objective-C class?
TroubleShooting
Mostly I've been trying various imports. Apple recommends the #import style here
But I have been trying multiple other varieties:
// Compiler Error
#import <SLPagingViewSwift/SLPagingViewSwift.h>
// Builds Fine -- Doesn't Work
#import <SLPagingViewSwift/SLPagingViewSwift-Swift.h>
#import "SLPagingViewSwift-Swift.h"
I've also been trying a few other Swift libraries from time to time to see if I could make anything click.
I don't see anything on the Cocoapods issues that can help this, I also didn't find anything in their blog / release stuff.
Note
If I add the SLPagingViewSwift.swift file separately to the project the old fashioned way, it works just fine.
I think you have to declare the swift class as public, otherwise it is treated as an internal class and can be only be seen within the same module, and this could be the reason why adding it to the same project as files work, but as a framework doesn't. Other thing that occurs to me is that the framework may need to add #objc in front of the class declaration so that it can be seen within objective-c classes. Also reading Apple's guide of Mix and Match between objective c and swift it says that when you import an external framework, you need to make sure the Defines Module build setting for the framework you’re importing is set to Yes. Have you checked with any of those options?
Jus use the
#import SwiftModuleName;
Syntax, and make sure the functions you want to use are public (and #objc)
In my case there was no “use_frameworks!” into podfile (old project).
I added it and then I was able to use import like that
#import "PODNAME-Swift.h"
and use classes from pod.
But finally I wasn't able to use that swift pod, because of lack objective c exposition. I believe this will be the issue in many cases.
I created a UIView inside the main view of a view controller using the storyboard editor and changed its class to FBProfilePictureView.
I created an outlet:
#property (weak, nonatomic) IBOutlet FBProfilePictureView *userImage;
However, when I refer to the userImage object in code it reports itself as a UIView.
NSLog(#"userImage class: %#", [userImage class]);
Produces:
2012-08-28 17:52:22.196 FBTestApp[6230:707] userImage class: UIView
What am I missing?
While I didn't see the error mentioned in the FB docs, adding:
[FBProfilePictureView class];
To applicationDidFinishLaunching did the trick. Presumably some runtime magic going on.
I wouldn't rely on [userImage class] for anything other than calling class methods. If you need to ensure userImage is the correct type, use [userImage isKindOfClass:[FBProfilePictureView class]]. It will let you know if you can treat the object as a FBProfilePictureView.
A more elegant way to resolve this might be adding the -ObjC linker flag instead of doing this "runtime magic" stuff. Here you can find instructions on how to add the flag!
See the SDK documentation, which says:
Note: If you've added the -ObjC flag to your linker options, then you don't have to add this code. Adding that flag causes the linker to load all the object files in the Facebook SDK, including the FBLoginView class. If you want to know more about what the -ObjC flag does, you can check out our troubleshooting guide.
It mentioned the FBLoginView, but according to the answer to this question, it also works for FBProfilePictureView: FBProfilePictureView object wont show image
Hope this helps.
I'm trying to learn some of the basics of developing OS X apps with XCode and Objective-C, but I am already running into problems.
I have a project I made from a while back which worked very well for me, however, when I try to replicate the results I had last time, I run into numerous errors.
I have two files, a .c and a .h named "AppDelegate"
in AppDelegate.h:
#import <Cocoa/Cocoa.h>
#import <WebKit/WebView.h>
#interface AppDelegate : NSObject {
IBOutlet WebView *gameFrame;
}
#end
then, in AppDelegate.c:
#import "AppDelegate.h"
#implementation AppDelegate
-(void)awakeFromNib
{
}
#end
In IB, there is an NSObject named 'AppDelegate' and its class is 'AppDelegate'.
However, when I try to run this, I get 11734 errors...
When I click on the error icon at the bottom of the XCode window, it lists a bunch of code that seems to be involving NSStrings, but I cant make any sense of it...
Also, within my code, the
#end
line in both the .c and the .h are highlighted with an error saying:
'Expected identifier or '(' before '#' token.'
I don't understand what XCode is tripping up on when it tries to compile, I don't see any logical place for a '(' to go and I don't think I left anything unidentified.
Any help would be appreciated.
That's because that isn't valid C code.
You named your module file AppDelegate.c, which indicates that it contains source code written in (more or less) pure C. But it does not: You wrote a class interface and implementation in Objective-C, which is a superset of C (all C is valid Objective-C, but not all Objective-C is valid C—in particular, classes aren't).
For this, you must name the module file AppDelegate.m (or anything else, as long as it ends with .m; naming it after the class is a convention worth following). The .m suffix indicates a module (usually containing a class implementation) written in Objective-C.
So, just rename your module file from AppDelegate.c to AppDelegate.m. Make sure you do this in Xcode, not the Finder: If you do it in the Finder, Xcode will only care that there is no longer a file named AppDelegate.c; it won't notice the rename.
For your convenience in creating future classes, Xcode provides a template in the “New File” panel for creating subclasses of certain Cocoa classes; your AppDelegate should be a subclass of NSObject, and templates are also provided for NSView, NSDocument, UIView, UIViewController, and a few others. The files created by the template will already have the correct extensions.
I've created a class using XCode3.2.1 and I want to make it inherit from NSViewController (or any other AppKit entity) .
#import < Cocoa/Cocoa.h>
#interface myCustomView : NSViewController {}
#end
I've linked in the Cocoa libraries, but I get the error that it can't find the class header file
Undefined symbols: "_OBJC_CLASS_$_NSViewController", referenced from:
_OBJC_CLASS_$_myCustomView in myCustomView.o
I have other classes in my project that are inherit Cocoa classes without a problem. I don't have any errors if I make it inherit from classes that are part of Framework or CoreData (eg NSObject, NSArray, NSEntityDescription).
Any suggestions?
Check if your subclassed NSViewController implementation file is in the "Compile sources" build phase of your active target.
Somehow the some of the Frameworks become disconnected in XCode.
Under if you control-click Frameworks and select GetInfo, it the
box had a dash through it (meaning it was partially selected).
Clicking it again activated it for all classes.
i am currently starting to learn Xcode and objective-c and i am reading three different books on that topic currently. All of these books refer to a file called "AppDelegate" (My_First_ProjectAppDelegate.m, My_First_ProjectAppDelegate.h) which are said to be "created with the Project" (i am creating a "Cocoa Application"). These files are not present when I create a new Project. I seem to be not the only one having this problem (see http://pragprog.com/titles/dscpq/errata ).
Is there any more information about AppDelegate? What is the current practice on how to deal with a missing Appdelegate? i am using Xcode Version 3.1.4 on Mac OSX Leopard.
AppDelegate is nothing more than a common NSObject class with needed connections in MainMenu.xib. You can easily recreate your own:
Create a class, name it AppDelegate
Open MainMenu.xib and add NSObject object to object palette
In object inspector's Identity tab (the last one) set object's class to AppDelegate (you should get autocomplete)
Ctrl+drag from Application object to your newly created AppDelegate object and choose "delegate" from opened panel.
As I recall, only the iPhone templates were providing delegate classes by default. This is not a huge deal, but I can see how you would be concerned if you are just learning. Are you sure what you are reading is relevant to MacOS applications and not Iphone?
You can always create your own delegate class manually. You just create a class as you normally do, then set it as the delegate for NSApplication in Interface Builder.
I think the confusion comes from the version of XCode you are using.
Xcode version 3.2 changed the default behavior when you create a new project: it now creates an AppDelegate for your project. I can't remember what the earlier versions did, but it was different.
As Eimantas says, if you want to use an AppDelegate then you can just create one following the steps he describes.