How do I access the source level definition of classes at runtime? - ios

How do I access the Objective-C class interface defanition that is collected from headers at (pre or actual) compile time so I can provide introspection that is true to the defined public interface.
Problem: F-Script, SuperDB, IKBClassBrowser, CBIntrospection use the class_copyPropertyList() family of functions to introspect objects at run time. While powerful, there are drawbacks…
the runtime has no concept of private and public… everything is
returned
I can not see a reliable way to access the to the ObjC types of
method arguments and returns
Goal: I am researching a iOS app to help teach coding via a live / immediate development environment (similar to SmallTalk, F-Script, SuperDB, IKBClassBrowser, CBIntrospection). I want users to introspect objects, send messages, create new objects, and build and run code via a VM. But I want to limit the functionality to public functions (there is no way Apple would approve the app otherwise) and I want to have access to types so I limit so users can only pass legal objects.
My hope is that there is some way to access Clang or the symbol file to pull this information in way I can use it at runtime. It does not have to be fully automated (I will probably want to limit functionality in some ways)

You're encountering one of the distinguishing characteristics of Objective-C: There is no such thing as private or public API. There's only documented API vs. undocumented API. You can call any method on any object at any time, regardless of whether it appears in a header file. Public/private distinctions exist only for the compiler; at run time, they don't exist, and there's no way to reverse the process and discern what the header files might have said.

Related

Core Data Sync With Multiple Users

I would like to sync a core data app with a user with a different iCloud ID and I am trying to figure out the most graceful way to do this. I do not want the data to sync with all users, but want to be able to sync among family members for instance. From the research I have done, I do not think I can do that using iCloud Core Data sync because it only syncs between devices with the same iCloud ID. I have looked at this stackoverflow answer and read a little bit about Ensembles, Parcelkit and TICoreDataSync, Parse etc., but it is not clear to me if any of those options will allow me to sync with multiple users. Does anyone have a good method for syncing a Core Data app with multiple users?
Ensembles and TiCoreDataSync might work. They can use Dropbox file syncing, so in principle they should work with Dropbox shared folders. I don't think these are the main intended uses, so I suggest contacting the developers and/or doing some good testing yourself before assuming this would actually work.
You'll need to think about the user experience, though. At a minimum, your users would both need Dropbox accounts and would have to set up a shared folder before beginning to sync data this way.
Parcelkit probably won't work. It uses Dropbox's data store API which, unlike other Dropbox services, doesn't appear to support shared data.
Services that do support this kind of sharing exist-- for example, Parse and Firebase-- but make sure to review their pricing carefully before using them. Also of course, there have been any number of projects that have their own custom server back end, but that obviously requires having someone on the team who can do that kind of work.
You need to think about other device types (Android at least) if you want your application to be reaching more users.
I'm doing the same now by the following way:
Setup an online database with proper web services (careful with implementation for security matters - DB should NEVER be exposed by anything other than the web services).
Create a Class for your communication with the server (using Class methods with security handling like authentication and authorisation).
Use the class in your app to communicate with the server (SQL operations are done on the server).
To integrate with CoreData you need to create the model in your app similar to the structure in the backend database. Then you need to create a similar class for the app that deals with only local CoreData.
A higher level class might be required if you want to make sure that operations done on both server and local data storage.
Besides, you have to implement a lot of conditions to make sure that data written in local ONLY after making sure that it is stored online (or create an engine for differed operations to run later).
Another Way if you are familiar with notifications:
Use structured notifications between devices for data operations in order to keep everything in sync with other users. The problem with this is the "Autonomy" of the operations. If two operations were done in approximately the same time, you have to find a way to make sure the order of the operations is done properly (maybe timestamp or something).
I'm looking into the same thing for my app and I 'think' you can do a fairly unsecured version of what you are after using using the public folder in cloud kit as mentioned in this question (no accepted answer at time of posting) : Private data sharing using CloudKit
You would need to find a way to differentiate between data that is truly public and those shared among the users you need and some level of authentication.
I'm going to try exporting a permission file with access permission in it to whomever I want to share with combined with a unique identifier located in that permission file.
Keep in mind, as mentioned in the comments of the linked answer, my implementation will be security by obscurity (thanks for that phrase) unless you find a way of adding proper validation to it but my data is relatively insensitive.
Hope this, or any ridicule in the comments, points you in the right direction : )

How to differenciate between Public vs Undocumented / Private API in iOS programmatically?

Is their a safe way to determine if class / method you are accessing is not restricted at runtime ?
Or
do these classes have some property which you check and safely avoid using them?
E.g. UINavigationTransitionView or UITransitionView are accessible but undocumented, hence I assume you are not allowed to use them.
Uhm, as the name implies, any method or class not documented in the public Apple documentation or in the SDK header files is considered private API and should not be used for AppStore submissions.
Note, that sometimes you may find yourself accessing public methods on private classes. This is generally acceptable, but it depends on your use.
There are also cases, where Apple has opened API and made public retroactively, meaning you can use a method for current SDK as well as call it on previous versions of iOS safely. Examples of this include NSArray's firstObject and NSDatas base64 API.
There's no way to check programmatically at run-time. In order to know whether you're accessing a private API, you'd need to know which SDK the app was built with, and then you'd need to check every function or method call against the headers from that SDK. Since iPhones don't generally have an SDK installed, there's no way to do that check at runtime.
If you use constructions like:
Class transitionViewClass = NSClassFromString("UITransitionView");
then it's impossible to determine it's access level (public or private) at runtime.
It's better to use direct access to classes/methods:
Class transitionViewClass = [UITransitionView class];
In this case compiler that Xcode uses will show warnings/errors that this class is undeclared:
Semantic issue: Use of undeclared identifier 'UITransitionView'

How to setup custom id-field in DB4O

I've read the documentation and samples multiple times and can't find out how to do this.,
I'm trying to wire up DB4O to use my own custom Id field. based on the documentation you can define your own IDs but as far as I can tell they won't replace Db4o's internal IDs, As in it won't actually use those Ids to identify the objects.
Basically all the examples do are tell Db4o to generate some sort of unique id and index it, I don't see anywhere on how to tell it that this is the ID that you should use.
Is it possible to have our own IDs on our model replace the internal IDs used to keep track of the relationships?
we need to have our own Ids since our system relies heavily on REST.
There no direct support for this. You need to create your own mechanism.
Simplest way: Use Guid on .NET. Or use a UUID in Java. In Java: Add UUID-Support: configuration.common().add(new UuidSupport());
Use callback to create new id's. Doesn't not work in TCP client/server.
See also this page.
Side note: You build a REST app. How many request does it need to handle? db4o is internally inherently single threaded. It can only handle a very limited load.

How many ways to share data among activities in monodroid?

I need to share some sensitive data among activities.
I have two EditText which are basically username and password
I am consuming a webservice which on the base of provided username and password return some user info (DataType:String). Like userid,useremail etc.. which is basically in CSV format
I need these piece of information throughout my application.But i can't figure out which is the better way.
-- One way i could found out so far is to use sqlite with MonoAndroid
-- Other way i found out is using Application class
I just started to learn android today , but i want to know if there are some other ways to share data ?
As you mentioned, a global Application class and the database are two good ways to share application-wide data. One thing to be careful with is that your Application class could be recycled when the app is in the background, so you would lose any data that hasn't been persisted to something more permanent.
In addition to the database, you can also persist data down to the filesystem as well. This recipe from Xamarin has an example of writing directly to a file. Most of the classes you'll need to do file access are found in the System.IO namespace. Mono for Android also supports isolated storage, which provides a higher level API for reading and writing files.
If you simply need to pass data directly between activities, you can do so by adding it as an extra to the intent. This recipe explains how to do that.
If you want to wrap up access to a particular resource in a more managed fashion that can be accessed by either other parts of your application or even external applications, you can look into implementing a content provider. Android itself provides several built-in content providers for resources like contacts and media, if you need an example of what it's like to use one. This recipe explains how to read from the contacts provider.

How to make contentprovider data available to all applications in android

i've used contentproviders with DB.it has some data in it.i need to make those data available to all other applications.How? Usually the main use of content provider is to store and retrieve data and make it accessible to all applications. They’re the only way to share data across applications; there’s no common storage area that all Android packages can access.I used the code from below link..
http://ashwinrayaprolu.wordpress.com/2011/03/16/custom-content-provider-in-android/
Distribute your Content URI and define your API.
Provide the string of your Content Authority and the paths you recognize. Explain to your users how the tables in your DB map to your paths. Document what the columns in your tables are. Users with your content URI can read and write your databases using standard calls to ContentResolver and the insert/delete/update/query calls.
Provide access control in your <provider> tag in your AndroidManifest.xml. Look at The documentation especially with regard to android:exported, android:grantUriPermissions, android:permission, android:readPermission and android:writePermission. You'll need to decide how to use those based on your use cases. Also, the <grant-uri-permission> tag will give you even more fine-grained control.
Write other apps to use those calls you just documented and allowed permissions for.

Resources