05 Jan 2020
|
fix
@Tom-ski reported that Security api like SecItemAdd
fails in RoboVM applications while running on simulator with error -34018:
The operation couldn’t be completed. (OSStatus error -34018 - Client has neither application-identifier nor keychain-access-groups entitlements)
Same time there is no issue for application when running on device. There are multiple reports about similar issues on web, and one on Stackoverflow contain reference to statement from Xcode8.1 release notes:
Keychain APIs may fail to work in the Simulator if your entitlements file doesn’t contain a value for the application-identifier entitlement.
Quick test reproduced this issue with Java code like this:
SecAttributes attributes = new SecAttributes();
attributes.set(SecQuery.Keys.Class(), SecClass.Values.GenericPassword());
attributes.setAccount("My key");
attributes.set(SecValue.Keys.Data(), new CFString("My secretive bee 🐝"));
attributes.setAccessible(SecAttrAccessible.WhenUnlocked);
try {
CFType res = SecItem.add(attributes);
System.out.println(res);
} catch (OSStatusException e) {
e.printStackTrace();
}
But there is an error possible in bindings, to check this native library with simple class was generated and called from RoboVM project:
@implementation SimpleTest
-(void) test {
NSMutableDictionary *queryAdd = [NSMutableDictionary dictionary];
[queryAdd setValue:kSecClassGenericPassword forKey:kSecClass];
[queryAdd setValue:itemKey forKey:kSecAttrAccount];
[queryAdd setValue:[itemValue dataUsingEncoding:NSASCIIStringEncoding] forKey:kSecValueData];
[queryAdd setValue:kSecAttrAccessibleWhenUnlocked forKey:kSecAttrAccessible];
int resultCode = SecItemAdd(queryAdd, nil);
NSLog(@"SecItemAdd %d", resultCode);
}
@end
And result was same error -34018.
the fix
Same time this ObjC code successfully runs on simulator from Xcode. That means there is something in build/signing process missing in case of RoboVM.
Looking throw Report navigator shows following:
- Xcode signs simulator binary with ADHOC identity. But it is not enough;
- Xcode adds entitlements during signing. But signing with simple
get-task-allow
(as mentioned in web) crashes App on start with Invalid entitlements
exception.
- It turns out that Xcode uses
com.apple.security.get-task-allow
instead. With it app doesn’t crash but Security API still doesn’t work;
- Inspecting binary built by Xcode for
application-identifier
discloses another entitlements (besides one in signature) stored in __TEXT __entitlements
and it contains following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>6THE3YW9HQ.bundle.id</string>
<key>keychain-access-groups</key>
<array>
<string>6THE3YW9HQ.bundle.id</string>
</array>
</dict>
</plist>
Having such section embedded into RoboVM application solves the issue. Success !
Bottom line
As result:
- signing of binary built for simulator is not required, but was added to be compatible with what Xcode is doing;
- RoboVM compiler now embeds __entitlement section similar to Xcode (but this is not documented anywhere).
Code was delivered as PR447
03 Jan 2020
|
binding
postfix
Report in gitter shown another problem in bindings:
java.lang.UnsatisfiedLinkError: Optional @Bridge method GLKMatrix4.create(FloatBuffer;)GLKMatrix4; not bound
Quick investigation shown that this method is not available runtime anymore as tons of functions converted into static inline. Today this functions looks as bellow:
GLK_INLINE GLKMatrix4 GLKMatrix4MakeWithArray(float values[16])
{
GLKMatrix4 m = { values[0], values[1], values[2], values[3],
values[4], values[5], values[6], values[7],
values[8], values[9], values[10], values[11],
values[12], values[13], values[14], values[15] };
return m;
}
As result RoboVM is not able to resolve it runtime and use it.
As long as it is not available runtime there are two options to use it:
- get all API and .c file, build it into object file and distribute as part of bindings;
- implement missing API in java (porting it).
While first option is preferable due performance concerns second approach will be implemented as quickest solutions. All changes were added to ios13.2 bindings branch as commit.
Other postfixes:
26 Dec 2019
|
bitcode
compiler
postfix
Bitcode was considered as big question once Apple introduced support for it. Mostly it was seen as danger for RoboVM project as Apple might use it as a blocking requirement and not allow application to be submitted without bitcode. While today lot of people think bitcode is not deliver significant benefits (if apple re-compiles apps on own servers) having it might be good idea due:
- developers need it due fear;
- it is required when producing Framework target with RoboVM and including framework in bitcode-enabled project;
- it was a part of commercial RoboVm 1.14 compier.
How support works
There is nice post Embedded Bitcode by Jonas Delieghere that covers basics. In case of RoboVM getting bitcode is not big deal as its an optimized form of LLVM IR that RoboVM compiler produces while building native code. The question is how to get it emited to object file. From post there are two option to mark object file as having bitcode:
- Full support: a section
__LLVM, __bitcode
for storing the (optimized) bitcode. This is plain, binary bitcode, not wrapped in an archive as there’s only one file for each object;
- Formal support: an empty section
__LLVM, __asm
to differentiate objects without bitcode from those built from assembly.
This post fix implemented formal support due following moment:
- to add bitcode as section to obj file would require implementing functionality similar to clang’s
-fembed-bitcode
as LLVM either produces bitcode, object or assemble file;
- RoboVM compiler does produce object file from assember file (it produces it from LLVM IR to hack method size fields in info object);
- genereting bitcode and allowing Apple to re-compile app will break line number and method information. As it being received from DWARF debug one, once recompiled by apple – offsets might not match anymore. And it would require to disable line number information in stack traces.
What was done
- native libraries were re-compiled with
-fembed-bitcode
flags;
- each object file generated from Java class now gets
__LLVM, __asm
section;
- linker is being instructed to use
-fembed-bitcode
;
- as runtime libraries are huge now due included bitcode – it being stripped of if not enabled to minimize debug footprint;
How to use
Bitcode support can be enabled:
- in
robovm.xml
with <enableBitcode>true</enableBitcode>
;
- in
robovm
setion of build.gradle
with enableBitcode = true
;
- in
enableBitcode
parameter to maven plugin;
Code is delivered as PR443
Other postfixes:
24 Dec 2019
|
binding
postfix
Apple altogether with introducing new APIs also keeps refactoring existing one. In this case it results in part of API being extracted from class and moved to newly introduced class. And this class is being used as new super.
Result class will have schema when super class introduced later than child. This makes problem when running code on iOS older than super was introduced.
Bright example:
// since ios 4.1
@interface GKPlayer : GKBasePlayer
// but
// since ios 10.0
@interface GKBasePlayer : NSObject
Root case
23 Dec 2019
|
binding
bro-gen
postfix
This post continues the series of fixes discovered during compilation of CocoaTouch library and improvements to compiler.
PostFix #7: iOS 13.2 bindings
While things being fixes iOS 13.2 is already in wild. This postfix delivers:
- changes to support new api;
- fixes in javadoc;
- fixes to structures that have to be annotated as packed.
Code is delivered as PR441
Other postfixes:
18 Dec 2019
|
fix
binding
bro-gen
postfix
This post continues the series of fixes discovered during compilation of CocoaTouch library and improvements to compiler.
PostFix #6: Fixes to Network framework bindings
As metntioned in gitter channel a try to use NWPathMonitor
fails with ObjCClassNotFoundException: OS_nw_path_monitor
. The binding of Network framework differs from common approach in way it is completely functional interface. Most of API might be simply grouped into two groups:
- creators: CLASS INST = function_Create()
- usage: function_Usage(CLASS INST, other params)
RoboVM bro compiler allow to use such functions as class memebers, e.g.:
function_Usage(CLASS INST, other params)
to
class CLASS {
@Bridge
function_Usage( other params)
}
Same time bro-gen extracts types defined in framework as protocols (like NWPathMonitor
is defined as OS_nw_path_monitor
) and closes binding for it is a NativeProtocolProxy
. Which shall work in general case but not this.
19 Nov 2019
|
whatsnew
What’s new
- [fixed] #408 Cannot compile AUMIDIEvent;
- [fixed] #414 Deployment to ios13 device, updated libimobiledevice lib’s bindings;
- [fixed] swiched to
simctl
to support Xcode11 simulator PR#410;
- [improvement] kotlin improvements: debugger and compilation PR#349
- [fixed] #387 CGBitmapContext.create fails on real device for big sizes;
- [added] support for packed structures PR#378;
- [fixed] Broken enum marshallers cleanup PR#377;
- [fixed] Debugger crashed when native thread exited while paused on breakpoint PR#384;
What’s in progress
Meanwhile work in progress happening in support for JDK12 tools on host branch, it contains following changes:
- all builds scripts reworked to allow building RoboVM using JDK9+ (works with JDK13) PR#400;
- ios13 bindings PR#406;
- Idea plugin workaround for long-going
android gradle
faset #242, PR#401;
- On-going series of Cocoa13-postfixes
Happy coding!
Please report any issue to tracker.
17 Nov 2019
|
fix
compiler
postfix
This post continues the series of fixes discovered during compilation of CocoaTouch library and improvements to compiler.
PostFix #5: Struct.offsetOf
always returns zero
Other postfixes:
Struct.offsetOf
is required to proper implement initialization of variable size structs with flexible array member such as:
struct vectord {
size_t len;
double arr[]; // the flexible array member must be last
};
Root case and fix
Struct
has offsetOf
definition and it returns always zero similar to sizeOf
method. `` its implemenation is being synthesized by RoboVM compiler and invocation of sizeOf
being fixed during trampoline phase from Struct.sizeOf
to DestStruct.sizeOf
(DestStruct – an example struct implementation).
Root case – compiler doesn’t not synthesize offsetOf
.
15 Nov 2019
|
bro-gen
binding
robopods
altpods
AltPods were update to v1.4.0-SNAPSHOTS to sync with recent releases. Part of list didn’t receive any API update hovewer bindings were re-generated against recent version of frameworks. Update list look as bellow:
Updated pod
Unchanged pod
These pods were pushed to https://oss.sonatype.org/content/repositories/snapshots
maven repo under 1.4.0-SNAPSHOTS
version.
Source code @github
Updates are not fullty tested, please open issue if bug found.
NB: AltPods – are robopods kept at my personal standalone repo. This is done to prevent main robopods repo from turning into code graveyard. As these pods have low interest of community and low chances to be updated.
22 Oct 2019
|
fix
compiler
postfix
This post continues the series of fixes discovered during compilation of CocoaTouch library.
PostFix #4: @Bridge annotated covatiant return bridget methods
Other postfixes:
Issue was discovered while compiling NWTxtRecord
:
java.lang.IllegalArgumentException: @Bridge annotated method <org.robovm.apple.network.NWTxtRecord: org.robovm.apple.foundation.NSObject copy()> must be native
at org.robovm.compiler.BridgeMethodCompiler.validateBridgeMethod(BridgeMethodCompiler.java:87)
at org.robovm.compiler.BridgeMethodCompiler.doCompile(BridgeMethodCompiler.java:233)
Root case and fix
In source code NWTxtRecord
doesn’t contain NSObject copy()
method but containts NWTxtRecord copy()
.
Hovewer once class file is decompiled following methods can be found there: