Reachability 2.2 vs 3.0 (Tonymillion) - objective-c

I have own static library that include Reachability for checking internet connection.
I use Reachability 2.2 version in my static library http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html
Other developer added my static library to his(3rd party project) which already has other Reachability (tag 3.0 in Pod's spec)
He installed it through Cocoa Pods. see the spec.
As you see, this is last version in pods.
Ok, project was builded without errors.
BUT we got error:
+[Reachability reachabilityWithHostName:]: unrecognized selector sent to class 0x2c77fc
I spent lot of time to find out the issue.
So Reachability 2.2 has declaration:
+ (Reachability*) reachabilityWithHostName: (NSString*) hostName;
But, Reachability 3.0 has following declaration:
+(Reachability*)reachabilityWithHostname:(NSString*)hostname;
Is it different?! Compiling was successful! Look at "HostName"... yeap, small "n".
And when we check host reachability inside static library we get unrecognized selector.
My question is - what best way to avoid this issue? Should I force other developers who want to build my static library use Apple's Reachability or something else?
Thanks

I know this is WAY late, but its a problem I also face, as I am sure anyone else who is trying to build a redistributable library.
There isn't a "best way" to avoid this issue unfortunately, but there are ways to do it, just depends on your use case.
A low-tech, possibly high maintenance and effort way is to rename all of the classes in all of the pods you use. By giving all of the classes a unique prefix, you almost guarantee that your "customers" integrating your static lib will not use the same name, and specifically in your case, if they use pods, then the will not have the same class names, avoiding the conflict.
Other methods would involve post compilation class name munging which would be more maintainable, but required deeper technical knowledge in how to do such a thing to an object file and linker mapping. Sorry, i don't have this productized yet!
Hopefully I am not overlooking a more simple and elegant solution, but this is where I am at.

Related

Can I add a category method to a Foundation class in a plugin

I have been working on an app, and wrote a lot of category methods on classes like NSNumber.
I now want to turn this into a Unity plugin. The code is now failing in this context, with -[__NSCFNumber int32Value]: unrecognized selector.
I have tried the -ObjC flag (OTHER_LDFLAGS) but that doesn’t seem to matter (I can’t add it when building the game engine).
I’ve looked at Objective-C categories in static library but don’t see anything that addresses this from the context of code in a plugin calling category methods it defines. Am I missing something?
Yes. I had seen a comment elsewhere on StackOverflow that you could not. But the real problem was that I had a build error, and the category in question was not in fact linked.

Warnings while using a plugin and static library in a cocoa project

I have a scenario where I need to use a plugin as well as a static library into my xcode project. The plugin will be dynamically loaded into the system. Now, the static library is also getting used in creation of the plugin.
While executing my project I am getting a warning saying :
Class A is getting referenced from /staticLibraryPath and plugin. One of them will be used.
Please let me know, how to resolve the warning or a better way of implementing the scenario.
The issue is a name class of the two ClassA types found in both plugin and library
I assume you have control over the source of either plugin / library.
.. rename Class A in one instance to make the names not clash -- I don't think there is another way to get rid of the warning/error

isMemberOfClass with static library linked twice

I'm working on few plugins for Quartz Composer, that all link to the same custom static library copied for each of them in the bundles frameworks folder. The plugins could be used separately, so I have to distribute the library in each plugin.
Everything goes well, apart from the isMemberOfClass and isKindOfClass methods. I read here that importing twice the same classes could be the origin of the problem.
I have no error at compilation.
Let's say that I have 2 plugins (NSBundles) that contains the lib XCode project and compile it before linking to it.
They both copy the lib in their resources folder.
Then, they both instantiate a custom hOzPolygon2D class from that library.
The first plugin return true to the test of the hOzPolygon2D object with isMemberOfClass method.
The second return false.
isKindOfCLass method returns the same "error".
I can't imagine a solution in my case. I'm really not a compilation professional and would really appreciate some help.
You should distribute the static library separately (possibly as its own framework). From the question title I assume you're seeing duplicate symbol errors from the linker. If you statically link the same static library into multiple other libraries and then try to link an application to more than one of those libraries you're bound to see these duplicate symbol issues. I haven't actually tried this with frameworks, but I know of this issue from linking iOS apps against interdependent static libraries.
You shouldn't worry about the fact that the modules can be used separately. Just make sure your users can also get the base library. This is a normal situation. For example AppKit and UIKit depend on Foundation, but neither of them actually contains a copy of Foundation.

How to check introduction of a feature at compile time in iOS?

If I use a feature which is deprecated at current SDK version, compiler will warn about it.
I'm finding a feature just opposite against it.
If I use a class or method which is not defined in specific SDK version, compiler warn about it.
How can I gain this feature? I tried defining __IPHONE_OS_VERSION_MAX_ALLOWED by putting definition on prefix-header like this,
#undef __IPHONE_OS_VERSION_MAX_ALLOWED
#define __IPHONE_OS_VERSION_MAX_ALLOWED 40000
but it catches any of version mismatch even in SDK itself. (such as UIKit)
I'm making library code needs backward compatibility for iOS 4.0, and I want some automated method to check backward compatibility. I know feature availability test won't solve everything, but this will make the work a lot easier.
How can I check feature availability for specific SDK version with compiler?
This sounds like a job for respondsToSelector, where you can check to see if a selector exists in the OS you are currently running on.
But if you really want to future-proof your app, you should always go for the newest API defined for the minimum OS version you want to support.
Here is a related question about 'respondsToSelector' that may help you out.
I think what you need is to check for a class (feature) before attemp to use it by using the NSClassFromString.
Class myClass = NSClassFromString(#"CLassThatYouWantToUse"); //get the class object
if (myClass != nil)
{
// The device will support this class.. so carry on...
}
else
{
// The device doesn't support this class.
}

Objective-C equivalent of Java packages?

What is the Objective-C equivalent of Java packages? How do you group and organize your classes in Objective-C?
Question 1: Objective-C equivalent of Java packages?
Objective-C doesn't have an equivalent to Java packages or C++ namespaces. Part of the reason for this is that Objective-C was originally a very thin runtime layer on top of C, and added objects to C with minimum fuss. Unfortunately for us now, naming conflicts are something we have to deal with when using Objective-C. You win some, you lose some...
One small clarification (although it's not much for consolation) is that Objective-C actually has two flat namespaces — one for classes and one for protocols (like Java's interfaces). This doesn't solve any class naming conflicts, but it does mean you can have a protocol and class with the same name (like <NSObject> and NSObject) where the latter usually adopts ("implements") the former. This feature can prevent "Foo / FooImpl" pattern rampant in Java, but sadly doesn't help with class conflicts.
Question 2: How to [name] and organize Objective-C classes?
Naming
The following rules are subjective, but they are decent guidelines for naming Objective-C classes.
If your code can't be run by other code (it's not a framework, plugin, etc. but an end-user application or tool) you only need to avoid conflicts with code you link against. Often, this means you can get away with no prefix at all, so long as the frameworks/plugins/bundles you use have proper namespaces.
If you're developing "componentized" code (like a framework, plugin, etc.) you should choose a prefix (hopefully one that's unique) and document your use of it someplace visible so others know to avoid potential conflicts. For example, the CocoaDev wiki "registry" is a de facto public forum for calling "dibs" on a prefix. However, if your code is something like a company-internal framework, you may be able to use a prefix that someone else already does, so long as you aren't using anything with that prefix.
Organization
Organizing source files on disk is something that many Cocoa developers unfortunately gloss over. When you create a new file in Xcode, the default location is the project directory, right beside your project file, etc. Personally, I put application source in source/, test code (OCUnit, etc.) in test/, all the resources (NIB/XIB files, Info.plist, images, etc.) in resources/, and so on. If you're developing a complex project, grouping source code in a hierarchy of directories based on functionality can be a good solution, too. In any case, a well-organized project directory makes it easier to find what you need.
Xcode really doesn't care where your files are located. The organization in the project sidebar is completely independent of disk location — it is a logical (not physical) grouping. You can organize however you like in the sidebar without affecting disk location, which is nice when your source is stored in version control. On the other hand, if you move the files around on disk, patching up Xcode references is manual and tedious, but can be done. It's easiest to create your organization from the get-go, and create files in the directory where they belong.
My Opinion
Although it could be nice to have a package/namespace mechanism, don't hold your breath for it to happen. Class conflicts are quite rare in practice, and are generally glaringly obvious when they happen. Namespaces are really a solution for a non-problem in Objective-C. (In addition, adding namespaces would obviate the need for workarounds like prefixes, but could introduce a lot more complexity in method invocation, etc.)
The more subtle and devious bugs come from method conflicts when methods are added and/or overridden, not only by subclasses, but also be categories, which can cause nasty errors, since the load order of categories is undefined (nondeterministic). Implementing categories is one of the sharpest edges of Objective-C, and should only be attempted if you know what you're doing, particularly for third-party code, and especially for Cocoa framework classes.
They use long names...
Article on coding style & naming in Cocoa / Objective-C
Discussion whether Obj-C needs namespaces (deleted, archive here)
See
What is the best way to solve an Objective-C namespace collision?
for a discussion of how Objective-C has no namespaces, and the painful hacks this necessitates.
Unfortuantely objective c doesn't have any equivalent to namespace of C#,c++ and package of java....
The naming collisions could be solved by giving contextual name for example if u gonna give a name to method it should imply the class and module that it comes in so that...these problems could be avoided.
Go through the following url to know more on naming convention as advised by apple
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html
What about something like this (inside a directory)?
#define PruebaPaquete ar_com_oxenstudio_paq1_PruebaPaquete
#interface ar_com_oxenstudio_paq1_PruebaPaquete : NSObject {
and importing it like this:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
PruebaPaquete *p = [[PruebaPaquete alloc] init];
and when you have name collision:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
#import "ar/com/oxenstudio/paq2/PruebaPaquete.h"
ar_com_oxenstudio_paq1_PruebaPaquete *p = [[ar_com_oxenstudio_paq1_PruebaPaquete alloc] init];
ar_com_oxenstudio_paq2_PruebaPaquete *p2 = [[ar_com_oxenstudio_paq2_PruebaPaquete alloc] init];
Well, I think all the other answers here seem to focus on naming collisions, but missed at least one important feature, package private access control that java package provides.
When I design a class, I find it is quite often that I just want some specific class(es) to call its methods, b/c they work together to achieve a task, but I don't want all the other unrelated classes to call those methods. That is where java package access control comes in handy, so I can group the related classes into a packaged and make those methods package private access control. But there is no way to do that in objective c.
Without package private access control I find it is very hard to avoid people writing code like this, [[[[[a m1] m2] m3] m4] m5] or [a.b.c.d m1].
Update: Xcode 4.4 introduced "An Objective-C class extension header", in my opinion, that is in some way to provide "package private access control", so if you include the extension header, you can call my "package private" methods; if you only include my public header, you can only call my public API.