I have a problem about making Mobile Substrate tweaks for iOS 5.
Most tutorial about making Cydia tweaks have this step: "Download private framework headers".
So, I downloaded it from : https://github.com/kennytm/iphone-private-frameworks
Since the private-frameworks are dumped from iOS 3.x, some new methods and variables are not included.
Therefore, I added these variables to my Tweak.xm. And I imported the private-framework-headers too.
For example:
#import "/opt/theos/include/UIKit/UIKit2.h"
#import "/opt/theos/include/UIKit/UIKeyboardLayoutStar.h"
#interface UIKeyboardImpl : UIView
#property(assign, nonatomic) BOOL showsCandidateInline;
#property(assign, nonatomic) BOOL showsCandidateBar;
#end
However, when I compile the tweak, I got these errors:
Tweak.xm:45: error: duplicate interface declaration for class ‘UIKeyboardImpl’
Tweak.xm:45: error: redefinition of ‘struct UIKeyboardImpl’
Tweak.xm:45: error: trying to finish struct, but kicked out due to previous parse errors
How can I do to fix this problem ?
Should I edit the private framework headers of iOS 3 and add new variables from iOS 5?
Thanks a lot
Adding a category will fix it.
#interface UIKeyboardImpl (YourCategory)
#property(assign, nonatomic) BOOL showsCandidateInline;
#property(assign, nonatomic) BOOL showsCandidateBar;
#end
Related
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
This is really weird. When coming back from school today and firing up my Mac Mini, I open up Xcode and I am presented with two errors in my AppDelegate.h file. One of these errors says Expected selector for Objective-C method and the other one is Expected method body. I googled these two errors and found nothing that could solve my case. I have tried restarting Xcode and as well as my computer. I have also tried "Cleaning" the project and still my problem is not resolved. What could this error be? Is it on my end? Or is this an Xcode bug? Thanks:
Code: AppDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UINavigationController *navigationController;
#end
Check Your main.m File for any extra or invisible Code:
//
// main.m
// Demo
//
// Created by Stackoverflow on 12/20/12.
//
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
What's in the corresponding .m file?
Are you #synthesizing accessors for your two properties? Failing to provide accessors (either synthesizing them or providing your own) seems like the most likely cause of the errors you've shown.
Have you implemented the usual app delegate methods? Off the top of my head, I'm not sure which if any app delegate methods are actually required, but your app isn't going to work very well and will produce some warnings if you don't have at least a -applicationDidFinishLaunching:withOptions:.
With Xcode newer than 5.0, Anyone confronting this issue can from the top menu\Product\Build.
It should resume right in the spot.
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...
I just downloaded the newest iOS SDK (4.3) and noticed that when I start a Window Based Application, the UIWindow is not declared in the header file, it is only mentioned as a property.
#import <UIKit/UIKit.h>
#interface GleekAppDelegate : NSObject <UIApplicationDelegate> {
IBOutlet UILabel *label;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
I would expect, and remember from older SDK's, that the above code should be
#import <UIKit/UIKit.h>
#interface GleekAppDelegate : NSObject <UIApplicationDelegate> {
IBOutlet UILabel *label;
UIWindow *window;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
Is that just a new feature of the SDK?
Thanks
The new Objective-C runtime has the ability to synthesize ivars without explicitly declaring them. From Runtime Difference in The Objective-C Programming Language:
In general the behavior of properties
is identical on both modern and legacy
runtimes (see “Runtime Versions and
Platforms” in Objective-C Runtime
Programming Guide). There is one key
difference: the modern runtime
supports instance variable synthesis
whereas the legacy runtime does not.
...
With the modern runtime, if you do not
provide an instance variable, the
compiler adds one for you.
From Runtime Versions and Platforms in Objective-C Runtime Programming Guide:
Phone applications and 64-bit programs on Mac OS X v10.5 and later
use the modern version of the runtime.
Other programs (32-bit programs on Mac OS X desktop) use the legacy
version of the runtime.
Also have a look at this questions:
Objective C: Why do we declare ivars in the .h member area if #property seems to do it automatically?
What is the underlying mechanism for ivar synthesis in the modern Objective C runtime
Automatic iVars with #synthesize
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.