Phonegap iOS custom context menu - objective-c

I'm developing a phonegap app for iOS, an would like to insert a new option in the context menu that shows up after selecting text. I had a look to several post which are quite related, and almost all of them led to this link. I followed the instructions of that example, but couldn't make it work, due to my lack of experience with Objective-c. Even so, I'm not sure if that one is a valid solution using Cordova/Phonegap, at least without hacking the framework.
Has somebody accomplished this task?

Related

Applying Non-Standard Power Assertions & Creating Virtual HIDs

I've got a big ask here, but I am hoping someone might be able to help me. If there's another site you think this should be posted on, please let me know.
I'm the developer of the free app Amphetamine for macOS and I'm hoping to add a new feature to the app - keeping a Mac awake while in closed-display (clamshell) mode while not having a keyboard/mouse/power adapter/display connected to the Mac. I get requests to add this feature on an almost daily basis.
I've been working on a solution (and it's mostly ready) which uses a non-App Store helper app that must be download and installed separately. I could still go with that solution, but I want to explore one more option before pushing the separate app solution out to the world.
An Amphetamine user tipped me off that another app, AntiSleep can keep a Mac awake while in closed-display mode, while not meeting Apple's requirements. I've tested this claim, and it's true. After doing a bit of digging into how AntiSleep might be accomplishing this, I've come up with 2 possible theories so far (though there may be more to it):
In addition to the standard power assertion types, it looks like AntiSleep is using (a) private framework(s) to apply non-standard power assertions. The following non-standard power assertion types are active when AntiSleep is keeping a Mac awake: DenySystemSleep, UserIsActive, RequiresDisplayAudio, & InternalPreventDisplaySleep. I haven't been able to find much information on these power assertion types beyond what appears in IOPMLibPrivate.h. I'm not familiar at all with using private frameworks, but I assume I could theoretically add the IOPMLibPrivate header file to a project and then create these power assertion types. I understand that would likely result in an App Store review rejection for Amphetamine, of course. What about non-App Store apps? Would Apple notarize an app using this? Beyond that, could someone help me confirm that the only way to apply these non-standard power assertions is to use a private framework?
I suspect that AntiSleep may also be creating a virtual keyboard and mouse. Certainly, the idea of creating a virtual keyboard and mouse to get around Apple's requirement of having a keyboard and mouse connected to the Mac when using closed-display mode is an intriguing idea. After doing some searching, I found foohid. However, I ran into all kinds of errors trying to add and use the foohid files in a test project. Would someone be willing to take a look at the foohid project and help me understand whether it is theoretically possible to include this functionality in an App Store compatible app? I'm not asking for code help with that (yet). I'd just like some help determining whether it might be possible to do.
Thank you in advance for taking a look.
Would Apple notarize an app using this?
I haven't seen any issues with notarising code that uses private APIs. Currently, Apple only seems to use notarisation for scanning for inclusion of known malware.
Would someone be willing to take a look at the foohid project and help me understand whether it is theoretically possible to include this functionality in an App Store compatible app?
Taking a quick glance at the code of that project, it's clear it implements a kernel extension (kext). Those are not allowed on the App Store.
However, since macOS 10.15 Catalina, there's a new way to write HID drivers, using DriverKit. The idea is that the APIs are very similar to the kernel APIs, although I suspect it'll be a rewrite of the kext as a DriverKit driver, rather than a simple port.
DriverKit drivers are permitted to be included in App Store apps.
I don't know if a DriverKit based HID driver will solve your specific power management issue.
If you go with a DriverKit solution, this will only work on 10.15+.
I suspect that AntiSleep may also be creating a virtual keyboard and mouse.
I haven't looked at AntiSleep, but I do know that in addition to writing an outright HID driver, it's possible to generate HID events using user space APIs such as IOHIDPostEvent(). I don't know if those are allowed on the App Store, but as far as I'm aware, IOKitLib is generally fine.
It's possible you might be able to implement your virtual input device using those.

Appcelerator Hyperloop vs. Plain Titanium Modules

I've started playing around with Appcelerator Hyperloop. While it seems great to access native APIs from JS from day zero, it does raise a few questions about architecture of the platform and the performance.
Currently (AFAIK) a Titanium app has a main UI thread (that runs the native UI controllers) and a JS thread (that runs the JS logic). Each call from JS to Native is passed though the "Bridge" (which is the expansive operation in an app).
Also, Titanium API doesn't cover all the native API and abstracts as much as it can. But if new APIs are introduced it could take time for Appcelerator to implement those into the platform.
One of my favorite things about Titanium is the ability to extend it (using objective-c for iOS and java for Android) - allowing to use native APIs that are not covered by Titanium, and also developing a really native performance controls in case we need to do anything that's too "heavy" for JS. And, as mentioned it's developed 100% native for each platform.
Now that Appcelerator introduced Hyperloop I've done a simple test app and saw that Hyperloop is not translated into native code but just to normal JS code:
var UILabel = require('hyperloop/uikit/uilabel');
var label = new UILabel();
label.text = "HELLO WORLD!";
$.index.add(label);
And another thing about it is that you have to run on the main thread.
So we basically have a few things come to mind here as far as Hyperloop architecture goes:
We still have a bridge? if Hyperloop is JS that calls "special" Hyperloop require then we still have a bridge, that now not only acts as a bridge but also needs to do some sort of reflection (which is also an expansive operation)?
Until now JS ran in it's own thread - so now running in a single main thread seems to be a potential source to more UI blocking operation.
The old-fashioned modules were truly native (not including the bridge call) - so how do Hyperloop-enabled apps compare with those?
There isn't much documentation or articles about Hyperloop that explain the inner working yet - so if anyone has any answers have been trying apps with it could be very helpful.
Answering your questions straight-forward:
There are no Kroll-Proxies involved anymore, since actual classes are being generated on runtime. This is done by using the hyperloop-metabase that does reflection (as you already said) to build an AST that grabs the actual signatures, types, classes, methods, properties, etc.
We did not see any performance-issues with running on the main-thread for now. If you do so, please file a JIRA-ticket so we can investigate the use-case.
The old-modules were "less native" then now, simply because they were all wrapped by the Kroll-proxy (by extending every view from TiUIView and every proxy from TiProxy / TiViewProxy. Hyperloop does not work with those, making the module-development much more faster by also allowing the developer to test his/her process live in their app without the need of packaging and referencing the module manually. Hyperloop modules are nothing else then CommonJS modules that are already used frequently across Alloy and other Ti-components.
I hope that gives you a quick overview on how Hyperloop works. If you have further questions, let us know!
Hans
(As a detailed answer to the above comment)
So let's say you have a tableview in iOS. The native class is UITableView and the Titanium-API is Ti.UI.TableView / Ti.UI.ListView.
While the ListView already provides a huge performance-boost compared to the TableView by abstracting the Child-API usage to templates, those child-API's (Ti.UI.Label, Ti.UI.ImageView, ...) are still custom classes that are wrapped and provide custom logic (!) e.g. keeping track of it's parent-references, internal data-structures and locks to jump between the threads.
If you now check the Hyperloop example of a native UITableView, you access the native API's directly, so no proxy behind it needs to manage sections, templates, items etc. Of course we deliver that API through a kroll proxy in order to display it in Titanium, but you don't "jump between the bridge" with every call you make from the SDK.
The easiest way to see that is to actually run some bigger example like the tableview, collectionview and view-animation. If you do a fast scroll through these, you already feel the performance boost compared to "classic" Titanium API's, simply because the only communication between your proxy and (like a Ti.UI.Window you want to add it to) is the .add() to receive the native API of the type HyperloopClass.
Finally, of course it still makes sense to use Ti.UI.ListView for example, because it comes with the builtin utilities that Titanium devs love (events, easy configuration and layout-handling). But thats also where the benefit of Hyperloop comes along, by allowing the developer to access those API's him-/herself.
I hope that helps a bit more to understand it.

Appcelerator Titanium - Alloy vs Classic

I'm about to start a new Titanium project. So far, what I've written is what's now considered as "Classic Project" (I've been writing Titanium apps since before Alloy).
I was wondering whether or not it's worth while to switch to Alloy for my new project. I know that basically, Alloy compiles to "Classic" Titanium code before compiling down to the java project or objective-c project. I also know about a big advantage in that "pre-compilation" process, which is to mark in alloy code that are relevant only for Android or iPhone and not including the other in the compiled "Classic" code.
My main concerns are flexibility - as with "Classic" I feel like I have more control over the code and what's going on.
Second concern, I have controls (like open sourced sliding menu) that are not written for alloy - how will I be able to have them as part of my project?
I started asking myself rather to use Alloy or not after finding (introduced in TiConf 2014) TI UX (https://github.com/jaraen/Ti.UX.Templates) which is written for Alloy.
few other questions:
how can I have old UI code run inside Alloy?
Can I have controls written for Alloy run in a "Classic" project?
Can "Classic" project also map out code not belonging to iOS/Android?
is there a difference in performance between Alloy projects and Classic projects? what about other flexibility issues?
Thanks
Just in case someone sees this question and needs an answer:
I have also posted this question in the Appcelerator Q&A where I got some answers here: http://developer.appcelerator.com/question/177739/appcelerator-titanium---alloy-vs-classic
The answer I was given is partial, and more info could be found in a questions asked here: http://developer.appcelerator.com/question/177542/classic-vs-alloy
I felt that the switch to Titanium Alloy from classic was right for me. I felt that classic Titanium development wasn't structured enough nor provided me with enough guidance on a good way to structure my app. Alloy provides a MVC structure to your code, but classic didn't completely prevent you from rolling your own or using one of the community libraries with MVC capabilities. In this respect I guess I would say it is more flexible to use classic over Alloy, because you can choose how to accomplish your structure, rather than fitting into Titanium Alloy's structure. That being said, I've never felt limited by Alloy.
How you develop in Titanium is your preference. There is no right answer to using Alloy or using classic. If one works better for you, use it. I feel that the structured approach to Alloy's separation of display and business logic provides me a structure that makes sense to me when developing an app.
I have not found that Alloy is less flexible than classic. Since you can use classic code in your Alloy project, you can pretty much do everything in Alloy that you can in classic. I'm sure that are some edge cases, that I haven't run into, where one might be easier than another when coding a specific type of application. It may be that classic is less flexible because I don't think you can use Alloy in your classic app. I don't believe the compiler would know how to build that.
Whenever I assess if I'm going to use a particular technology, I make a series of experimental mini programs to make sure all the capabilities are present for my application's requirements. If I feel that it doesn't fit or it is too difficult to reach those requirements, I don't use that technology. For example, when I switched to Alloy, I made sure the Ti.Paint library would still work. If it didn't I would still be using classic.
Just like classic, there are controls for Alloy. There is a pretty slick Alloy-based sliding menu module out there already. I use the Ti.Paint library, which existed before Alloy and isn't an Alloy specific module.
http://gitt.io/ is a decent starting point for finding Alloy modules/widgets.
index.xml
<Alloy>
<Window id="win">
<View id="content" />
</Window>
</Alloy>
1) In your index.js file, you would have the following to use classic coding to manipulate an Alloy view.
index.js
var myview = Ti.UI.createView({
backgroundColor: 'green'
});
$.content.add(myview);
2) I don't think you can use Alloy code in your classic project. As you mentioned before, it needs to do translation on the code and a classic project would likely skip that step in the process.
3) Are you asking if you can include or remove parts of the code based on if it is Android or IOS specific? You could probably do this with include/require statements strategically placed between if (Ti.Platform.osname == "android") statements to require in or not the code you want. If the code is for Android, require this one, if it is for IOS, require in that one.
4) Never attempted to check the performance between classic and Alloy-based projects. I think, since I switched and never noticed an issue that bothers me or my customers, I never put much thought into it. It is entirely possible that Alloy auto-generates code that is in some cases slower. I've never noticed it.
I feel that the efficiency I gain in using Alloy far outweigh that as an immediate concern. Plus, if I felt that I didn't like the way a particular control was created through Alloy, I could use the classic code and define that control myself having all the control of a definition from a classic project.

Creating a simple, single-view Quartz app

I'm an Objective-C newbie. Most of my experience is in Java. Also, I've never really used Xcode before and so I'm pretty new at that as well.
I'm trying to create a simple, single-view Quartz OS X app (not iOS) to display agent-modeling simulations. The graphics are pretty simple; just colored squares and grids. I have been looking at Quartz tutorials and I can see how I could accomplish this (as far as drawing things are concerned). What I can't find is an example that tells me how to tie it all together. What do I put in AppDelegate? Do I need a WindowController? How do I link that up with AppDelegate? I got as far as creating a Quartz Composer View in Interface Builder for my app, but I have no idea where to go from there.
As I mentioned before, I've looked for numerous tutorials but there is nothing that I can find that gives me information as far as linking everything together.
You should visit this web page before you do anything else. It will show you how a Cocoa application is structured and where the appropriate entry points are to place your code.
While the entire article merits reading, visit the section "Entry and Exit Points," which best addresses your particular questions.

Objective-C playground?

Is there any sort of Mac app, Web app, or others like JSFiddle for Objective-C/Cocoa purposes?
It's not entirely the same, but look into F-Script: http://www.fscript.org/
It lets you rapid-prototype and experiment. You can also hook it into existing apps very easily. It has been invaluable for me for certain types of UI debugging.
I've also found CodeRunner to be quite handy for boilerplate app generation and one-click console running to try language snippets out. Available on the AppStore at a price.
I created playgrounds for Objective-C on top of code injection, so you can experiment with normal iOS simulator, it's open source on GitHub
Video showing them in action