I was given an static library (.a extension file) that I have to use in a project, however I need to modify some of the source code before it is useful to me. What is the best way to accomplish this?
The easy-but-most-of-the-time-not-applicable solutions are subclassing or extending.
You can also try to decompile the .a file if its licence authorizes it: cf. Decompiling Objective-C libraries, but it can be tricky and/or illegal.
You cannot modify a static library, your best bet is to try to get access to the sources or ask the author to modify it for you.
You may use a Objective C extension.
For example, there's a [MyClass myMethod] in the .a lib, and you want to change this one, the following code might be used:
#import "MyClass.h"
#interface MyClass( CategoryName )
-(void)myMethod;
#end
#implementation MyClass( CategoryName )
-(void)myMethod
{
//new implementation goes here
}
#end
You cannot modify a library, only extend. That's kind of the point - to distribute the functionality behind your code without people being able to read it.
Related
It seems this has been asked before, however I have not found an answer that works for me.
Setup: I am currently creating two static library, that are used in a project. So lets say I have Project, Liba and Libb. Project links to both Liba and Libb, Libb has an import tag for Liba. Project does not directly use Liba, but I have it in the workspace because I have read that we are not supposed to have a library directly link another library. Surprisingly this all works. Where I run into issues is that I want Libb to also use StackMob. For some reason Libb can't find StackMob.h when importing. I have added the Stackmob library to my workspace in a similar way I have for my other libraries.
Here are the relevant code snippets of each class.
Project.h
#import "Libb/Libb.h"
#interface project
{
Libb* _libb;
}
#end
Project.m
#implementation Project
{
_libb = [[Libb alloc] init];
}
#end
Libb.h
#class Liba
#class StackMob
#interface Libb
{
Liba* _liba;
}
#end
Libb.m
#import "Liba/Liba.h"
#import "Stackmob.h" //This is where I get the error. I have also tried "StackMob/StackMob.h"
#implementation Libb
{
//Code here....
}
Thanks for the help. If you need me to clarify, please ask. I realize some of the code I provided is not necessary, but I thought it may help understanding how I have things setup.
Add $(SRCROOT)/../StackMob/Headers to Header Search Paths in build settings to allow the project to find the header files.
Pretty basic stuff but i am unable to troubleshoot where the problem is. In my project, i have a class named "TheFeedStore" with following two methods:
- (BOOL)hasItemBeenRead:(RSSItem *)item
{
............
}
- (void)markItemAsRead:(RSSItem *)item
{
.........
}
I am using the following class method so other classes can access these methods using it:
+ (TheFeedStore *) sharedStore
{
static TheFeedStore *feedStore = nil;
if (!feedStore) {
feedStore = [[TheFeedStore alloc] init];
}
return feedStore;
}
In one of my another class, i can easily access the above methods by writing
if ([[TheFeedStore sharedStore] hasItemBeenRead:item])
or
[[TheFeedStore sharedStore] markItemAsRead:entry];
But in another class if i try to access these methods in a similar manner, i get the error "No visible #interface for 'TheFeedStore' declares the selector 'hasItemBeenRead:"
1) I have imported TheFeedStore.h file in the classes from i am
accessing these methods of TheFeedStore class.
2) I have checked like 10 times and there is no typo.
3) The methods i am accessing are also declared in the header file of
TheFeedStore.h
UPDATE: Just to check, i have declared another test method in TheFeedStore.h, same result, one class can access the newly created method while rest of the three classes cannot.
UPDATE: I have tried creating more methods in the TheFeedStore.h just for troubleshooting this issue. The new methods are also not accessible from the other classes. But if the return type of these new methods is (RSSChannel*) which is another model class in my project, than they become accessible. If their return type is other than some class like (void) and (BOOL) then they are not accessible. Here is my TheFeedStore.h https://gist.github.com/jessicamoore112/5558473
You have said that you are using #class instead of #import in your header files, the methods that you are trying to access are declared in the header files and there are no typos of any kind.
In such cases, usually no body points this issue but i am going to do it anyway because i have faced such issues many times. You have probably created many copies of your project to work on each functionality and also keeping a working project.
When you do this, sometimes Xcode is still using the older copies of few files. That means it is still using the older copy of the TheFeedStore.h when the methods you are trying to access were not declared by you.
How to solve this problem is very simple. Go to the file from which you are trying to access the methods and the files in which these methods are declared.
In the Utilities section on the right hand side, check the location and full path under "Identity and Type" area.
First check the names of the project, if it is different from the project name that you are working on, that means Xcode is still pulling the old copies of the files from the previous revision of your project. See the blue arrows where the project name is 13SampleMoreRequests in my case.
If this name is same as your project name, then my answer does not solve your problem. If its different, you should use the new copies of the file by browsing the new location using the sign that is pointed out by red arrow.
Once you browse and use the new files, your problem will be solved and you will be able to access the methods. If you still can't, copy these files, delete from the project and then add them again and you won't face this problem.
Hope this helps!
Cyclical imports, e.g. A.h imports B.h while also B.h imports A.h is the most common problem.
In C, cyclical imports won't work and one of the imports will be silently ignored. Make sure you are not having a cyclical import. If you do, solve it (e.g. using forward declarations).
Import problems can be also easily inspected if you generate the preprocessed output (you can find it in one of the Xcode menus).
That might sound silly, but I have similar cases once in a while and sometimes just simple quitting and starting xcode helps, it tends to stuck sometimes.
Also, sometimes cleaning the project helps.
'Cause I have very similar to yours singleton code and it works fine.
Guys I had encountered the exact same issues. After some searching on SO and the search engine I was able to solve it.
In my Case I have four files:
RadioStation.h
RadioStation.m
ViewController.h
ViewController.m
My mistake was to place all my methods in RadioStation.m and only put my variables on radioStation.h
So when I import radioSation.h on my ViewController.m and try to define methods for button-click on my app that's where the problems started.
I got the error/warnings "ARC Semantic Issue: No visible #interface for Class declares the selector" every time I built or ran the app simulator.
My Solution was to go back to RadioStation.h file and just declare all my methods there.
Since they were already defined on RadioStation.m I was good to go.
So make sure you have properly declared your methods on the file that is going to be imported on your viewControllers.
Hope that helps.
In my case I had some very strange path entries in
Framework Search Paths
Library Search Path
(Targets -> YOUR_APP_NAME -> Build Settings in "Search Paths" section)
I removed them and the error messages are gone.
So after an hour of research, I've found that most people seem to agree that the function at http://www.thismuchiknow.co.uk/?p=71 is the way to go for implementing a Haversine function into an iPhone project for ordering results by distance when you have a database full of latitudes and longitudes. There seems to be little help on how to actually include it in your project though, and I'm having no luck on my own.
No matter where I add the function into my ViewController.m file, I get the error expected ')' before '*' token. Some people have mentioned you need to put static void distanceFunc(sqlite3_context *context, int argc, sqlite3_value **argv); into your .h file, but I get the same error there too.
Can anyone provide a brief example of including this function in an iPhone project?
your can use this,
+(void)distanceFunc(sqlite3_context *context, int argc, sqlite3_value **argv);
or change .m extention of your viewController file to .mm.(You can try this one also)
updated
+(void)distanceFunc:(sqlite3_context *)context arg1:(int)argc arg2:(sqlite3_value **)argv;
try updated one.
Thanks,
There should be no problem with inserting the code in the link you gave anywhere in a .m file. If you are getting the error on the function definition line, it is likely that the compiler doesn't know what an sqlite3_context is. This means you haven't include the sqlite3.h header in your .m file.
Ok, so my problem was a combination of not using #import <sqlite3.h> and not adding the libsqlite3.0.dylib framework to my project. As far as where to place the function from http://www.thismuchiknow.co.uk/?p=71, I put it between my #import tags and #synthesize in my controller's .m file, appearing just as it does in the blog post.
So I'm using the Static Library template included in Xcode. Right now just trying to build a simple template to see how static libraries really work.
Anyways in my static library I have two classes:
mylibrary (.h/.m) - This is simply an NSObject
modalView (.h/.m) - This is a UIViewController
The problem though is when I build the static library. The project builds the mylibrary.a file... however there is no "Headers" folder in the output. This means that when I add the library to my other project it gives "undefined" errors because it can't find the .h file for myLibrary.
Any ideas on how to fix this?
Thanks
You need to drag .h files to the new project, along with .a file
I have a bunch of scripts here:
https://github.com/drekka/dUsefulStuff/tree/master/scripts
Which I use to build static libraries and frameworks. You might find them useful in helping to assemble your library. The main (controller) build script is here
https://github.com/drekka/dUsefulStuff/blob/master/build.sh
I am working on an application where i have to use several constants.I want to declare all those constants in one single .h file.Can any one suggest me a way to achieve this.
Thanks in advance.
You can define all required header files and constants in the ProjectName_Prefix.pch(located under the Other Sources folder of your project) file.In this way you are not required to declare the libraries,constants required in multiple classes.
Cheers
create constants.h put all you constants into it and #import "constants.h" in your Prefix.pch
or if you don't want to recompile the whole project if you change something in constants.h just import the file in the sourcefiles where you need it.
The latter approach saves a lot of time if you use an old mac mini for development on a project which has 200MB of png files.