I'm currently trying to implement an ILocationListener on a class in order to receive GPS updates - this is not on an Activity, just a normal C# class.
As part of the ILocationListener contract I need to support I JavaObject:
public IntPtr Handle
{
get { throw new NotImplementedException(); }
}
What should I do for this?
Also, are there any good documents and/or blog posts out there which talk about how C# classes and Java objects are bound together in MonoDroid - if I can find those documents, then I probably won't need to ask questions like this and I'll hopefully also be writing much better code.
Thanks
Taken from Xamarin's docs:
There are times when you may need to implement an Android interface, such as Android.Content.IComponentCallbacks. Since all Android classes and interface extend the Android.Runtime.IJavaObject interface, the question arises: how do we implement IJavaObject?
The question was answered above: the reason all Android types need to implement IJavaObject is so that MonoDroid has an Android callable wrapper to provide to Android, i.e. a Java proxy for the given type. Since monodroid.exe only looks for Java.Lang.Object subclasses, and Java.Lang.Object implements IJavaObject, the answer is obvious: subclass Java.Lang.Object
Basically you should always inherit from Java.Lang.Object in these cases, as implementing IJavaObject yourself won't actually work since Mono for Android won't generate the callable wrapper.
If it helps, I have an example implementing ILocationListener available here. It implements it directly on an activity, but you can inherit from Java.Lang.Object instead of Activity.
I think I've found the first piece of the puzzle myself - it seems like there is a Java.Lang.Object handy and I can use that.
I'll continue to look for the binding information - hopefully I'll then know what I'm doing :)
This also solved my Seg Fault crash [mono-rt] Got a SIGSEGV while executing native code..... problems that was being caused by a Class that implemented IJavaObject!
Related
Recently i caught with the a thought of changing the implementation of method after deployment
When i googled about objective c runtime and all, came to know about method swizzling methodExchangeImplementations etc.
I know that it could be possible by https://rollout.io/
But my thought is how to do Hot Patching by myself for simple things.
my idea is injecting the code using webservice call.
Webservice should give a replacement for particular method.
That string has to be converted to executable code
What i want to know is ...
How to inject the code in existing method of enterprise application.
For ex:
Consider this method in objective c
-(void)fetchTheResult{
// some code lines
}
After deployment i would like to change the method implementation to
-(void)fetchTheresult{
NSLog(#"test log");
//some Code lines
//some more lines
}
Please guide me the way to achieve this
This is a big question and you've some research to do to figure out an answer. Here as some things you can look into:
First you've referenced Rollout, you could follow the same idea and send your update as JavaScript. You'll need to study how to call JavaScript, swizzle methods, and probably dynamically add methods - more on that in a moment.
An alternative you can investigate is dynamic library loading - you can open, and call code in, a library which your app loads at runtime. So you could look at sending your update as a library. You'll still need to do method swizzling and probably dynamically add methods...
As well as method swizzling you may find you need to dynamically add methods - e.g. so you have something to swap the existing implementation to. A good place to find out how to do that is Mike Ash's writings on KVO - go DuckDuckGo (or Google)
HTH
It is not as easy as you think, at least in Objective C and other similar compiled languages. This kind of runtime changes to the code is only possible in interpreted languages like Javascript.
The basic problem is, the apps are not allowed to change the executable files themselves. The apps on iOS and Android run in a sandboxed environment, and thus have access to limited disk locations only.
Also, after compiling the code, the code does not know where the part of code is converted and stored in machine language. You have to understand the basics of compilers to understand this. There are heavy optimisations happening to your code during this process.
As an experienced Objective-C developer who is now learning Swift , I'm really missing some of the reflection and dynamic features of Objective-C.
For eg: I had written a JSON serializer which automatically mapped keys and values using KVO and Objective C introspection , and there are open source libraries like Mantle which do this.
I could declare my object as an NSObject subclass and proceed but I feel that this is not the Swift way of doing things.
Is there any other way to accomplish the same tasks , while avoiding boilerplate , using what Swift provides ?
EDIT: (2016) this answer is auto-dated. Some of the advice may still be relevant but now that Swift is open-source, I would look into other possible answers.
There is no native KVO reflection like what you described built into Swift. See:
https://stackoverflow.com/a/24092370/798682
And based on what we do know about how the Swift compiler optimizes method execution at compile time (vs the pure runtime implementation of ObjC) it doesn’t seem likely to be added anytime soon. See https://stackoverflow.com/a/25438299/798682 and
http://blog.untitledkingdom.co.uk/obj-c-vs-swift/
for more info on that.
With all that being said, here is a blog post on some KVO alternatives in Swift:
http://blog.scottlogic.com/2015/02/11/swift-kvo-alternatives.html
and another that details some of the reflection capabilities that are in Swift:
http://freecake.angelodipaolo.org/simple-reflection-in-swift/.
This might be really generic and rather about the framework in general than a programming question. But, in the light of Swift, and the tedious and sometimes impossible tasks you have interacting with C APIs, that question is very relevant.
When building a new app for iOS, I discovered that you can really have a hard time working with address book framework. First, there is the uncomfortable pointer passing that you have to do for many CoreFoundation Methods. Secondly, the functions mostly return that ugly Unmanaged objects, where you have to figure out if they are retained or not (ARC is several years old now!). Accessing the properties through their identifiers is terribly cumbersome and far from typesafe. And lastly, since there is no C Function Pointer Support yet, you can´t even call ABAddressBookRegisterExternalChangeCallback(addressBook: ABAddressBook!, callback: ABExternalChangeCallback, context: UnsafeMutablePointer<Void>) because the ABExternalChangeCallback is so far only defined in Objective-C!
Then I found that there is some nice Objective-C Api in the Mac OS Version of AddressBookFramework. How unfair! Isn´t the iOS Frameworks younger? Why do you think Apple did this? And when will they change this in your opinion? Did I miss something, and is there an Objective-C Api for iOS, too?
Any suggestions for how to tackle above problems in the most convenient and beautiful way are welcome, too! For my part, I´m writing a complete wrapper to obscure all the nasty pointer- C-Function- and global constants uglyness. As soon as it´s ready I´ll commit it to StackExchange and maybe Github to let others benefit and discuss my solution.
EDIT: finally managed to upload my wrapper to GitHub. See
https://github.com/SocialbitGmbH/SwiftAddressBook
I agree with you about what iOS provides to access to the address book.
I've posted an answer explaining how I handled the problem, using some functional aspects of swift, and how I dealt with extracting unmanaged objects.
Briefly:
I defined a custom operator to allow me chaining function calls to transform some input data
I implemented 2 generic functions to extract unmanaged objects
posted some code to show how I access to the address book, loop through all contacts, and retrieve some data for each one
Recently I have get a reject from Apple because a use of a private API. I don't know exactly what is a private API nor an undocumented method. Could someone explain me what is an undocumented method and a private API? I'm really confused with that...
Follow up:
What is exactly the "official documentation"? Can I use some frameworks and classes made by thirds such as the Amazon one?
A private API or undocumented method is any object or method that is not part of the official documentation. In Objective C, and some other languages, it is relatively easy to find the list of methods (messages) that an object supports as well as the objects underlying the framework. (For example, just go into the debugger and look at the view hierarchy. You will likely see several view objects that don't exist in the documentation.) Sometimes you will even see instructions on how to use these methods and objects on the web.
One example that leaps to mind is -UIWindow _autolayoutTrace, I use it all the time when debugging autolayout, but it isn't documented and the leading underscore is a hint that you shouldn't be using it. That's fine for debugging, but if I shipped code that used that method it would be certain to be rejected.
But Apple specifically scans for these undocumented methods as part of the App Store review process and rejects apps that use them. This is because Apple might change how these undocumented methods work at any time. If your app was dependent on one of these hidden classes or methods your app might break when Apple released a new version of the SDK that changed this behavior.
There's a set of functionalities that Apple uses internally but are not publicly available for developers.
Any usage of such APIs will result in a rejection of the application by Apple.
I want my application to run on iOS 3.0 and later and be a universal application.
My problem here:
What do I do, if my class needs a property of a class that's only introduced in a later SDK?
For example:
My class needs a property of a UIPopovercontroller, but that's only available in 3.2 and later.
Do i need to work around by defining a property of NSObject instead and then casting around to UIPopoverController all the time?
Take a look at this post on Cocoa with Love for more info about combining compile-time and run-time checks for class and method availability. The preprocessor macros that Matt Gallagher developed and posted there may meet your needs. You would have to adapt them a bit to nuance the distinction between 3.2 and 3.0, though.
All of that said, there aren't a lot of users on 3.x (as of January 2011, it was ~10%, now undoubtedly much less.)