Open GoogleCodeExporter opened 9 years ago
Whoops. Just noticed a bug in the copy resources snippet I posted here.
The step 1 to copy all resources into a resources directory should be:
<copy todir="${xcoderes.path}">
<fileset dir="src" excludes="**/*.java"/>
<fileset dir="lib/impl/cls" excludes="**/*.class"/>
</copy>
Because the lib/impl/cls directory will contain .class files, not .java files.
Original comment by st...@weblite.ca
on 29 Jul 2013 at 8:39
I don't understand how this works. The problem is that xmlvm flattens the
hierarchy not us. Where do you update xcode with the files if XMLVM doesn't do
that?
Original comment by shai.almog
on 31 Jul 2013 at 12:37
XMLVM only needs the .h, .m, and .class files in order to to its work. It
outputs an Xcode project.
With the resulting Xcode project, I add a build phase that tells Xcode to copy
all of the runtime resources into the project build directory during its
compilation.
I did this by:
1. Convert the .pbxproj file into an XML property list (instead of the old
format) using plutil (because XML is easier to work with)
2. Add a PBXShellScriptBuildPhase entry to the .pbxproj file. It looks like
the following in the .pbxproj:
<key>e4e5a3214a4462a5fd77109d</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array/>
<key>inputPaths</key>
<array/>
<key>isa</key>
<string>PBXShellScriptBuildPhase</string>
<key>outputPaths</key>
<array/><key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
<key>shellPath</key>
<string>/bin/sh</string>
<key>shellScript</key>
<string>cp -r "${PROJECT_DIR}/../resources/" "${BUILT_PRODUCTS_DIR}"</string>
</dict>
The buildActionMask just needs to be exactly that value (2^32-1). The key just
has to be unique among keys in the project file.
So this just tells Xcode to copy all of the files in the resources directory (a
directory that I have previously filled with *only* the runtime resources) to
the ${BUILD_PRODUCTS_DIR} which is an Xcode variable for the application bundle.
This results in a bundle that has all of the runtime resources in it with
preserved package structure.
3. Build the xcode project (I guess you guys are using pbxbuild).
Note 1: I had originally thought that I needed to convert the .pbxproj file
back to its original form for Xcode to accept it, but it turns out you can just
leave it as an XML property list and it will still work fine.
Note 2: The PHP script I attached, handles all of the parsing and converting of
the .pbxproj file and insertion of the build phase. The closest thing to a
main() method in that script is:
/**
* A build script that prepares the XMLVM xcode project. Adds the
* build phase to import resources into the app bundle, and also
* adds file references for the specified files.
* @param type $path
* @param type $filesToAdd
*/
function prepareXcodeProject($path, $filesToAdd = array()){
$proj = new XCodeProject();
$proj->load($path);
$proj->addShellScriptBuildPhase(array(
'shellPath' => '/bin/sh',
'shellScript' => 'cp -r "${PROJECT_DIR}/../resources/" "${BUILT_PRODUCTS_DIR}"'
));
foreach ( $filesToAdd as $file ){
$proj->addFileReference(array(
'name' => basename($file),
'path' => $file
));
}
$proj->save();
}
What it does is probably self explanatory.
Original comment by st...@weblite.ca
on 31 Jul 2013 at 4:37
Oh.. one more thing. After adding the build phase to the project file, I
needed to add this build phase to each target in the project.
This is the PHP code that does this:
// Now we need to add it to our target
$xpath = new DOMXPath($this->dom);
$keys = $xpath->query('//key');
$arr = null;
foreach ( $keys as $key ){
if ( $key->nodeValue == 'buildPhases'){
$arr = $key->nextSibling;
while ( $arr != null and (!$arr instanceof DOMElement) ){
$arr = $arr->nextSibling;
}
break;
}
}
if ( $arr === null ){
throw new Exception("No targets with build phases found");
}
$strEl = $this->dom->createElement('string');
$strEl->nodeValue = $buildPhase['key']->nodeValue;
$arr->appendChild($strEl);
Essentially it looks for a tag like <key>buildPhases</key> which will always be
followed by an <array> tag with <string>ID</string> children.
I just add a <string>xxx</string> tag as a child of this where xxx is the key
of my build phase. In the example I posted, it would be
<string>e4e5a3214a4462a5fd77109d</string>
Original comment by st...@weblite.ca
on 31 Jul 2013 at 4:47
We are using xcodebuild and going into those scripts probably wouldn't be
something we will do in the near future unless we need to completely overhaul
everything. There is so much functionality on top of this its just not
practical to convert it.
Original comment by shai.almog
on 31 Jul 2013 at 4:51
I can understand the reluctance to want to tinker. Hopefully at some point
you'll have other use cases that will be more compelling for you to make this
change. To me, this is a pretty big deal but it's not a show stopper since I
don't need to use the build server. The build server preserves package
structure for Android, and I can perform offline builds for iOS.
Original comment by st...@weblite.ca
on 31 Jul 2013 at 4:58
I'd like to have a solution for this but I'm looking for something that is
guaranteed to be portable. E.g. character type X on os Y might fail for me. JAR
solved these things nicely but you are asking to do this with the native
structure which I don't want to rely on.
Furthermore, the advantage of being able to package resources into a RES file
will solve one of the more painful aspects of HTML programming since we would
be able to use multi images for image resources.
No its not the standard but neither is doing something different for every OS,
it could work exactly as it does in the simulator which means consistency.
Original comment by shai.almog
on 31 Jul 2013 at 5:16
If there is a solution to, say, copy a directory structure with subdirectories,
etc.. into a resource file and allow them to be addressed using a namespacing
mechanism, and have this compatible with native components like the browser
component, that that would be sufficient. To me that sounds like a difficult
thing to do.
I'm not sure I understand the issue of portability. Can you elaborate on the
"character type X on os Y might fail for me" example and how it might relate
maintaining directory structure of resources? Are you talking about characters
in file names causing problems for the file system?
Original comment by st...@weblite.ca
on 31 Jul 2013 at 5:32
Adding the hierarchy to the res file should be pretty easy. The only issue
would be in supporting the URL type for browsers, I was hoping you would have
some input on that assuming I can get an input stream...
E.g. local UTF-8 characters are very common and people use characters like % in
file names. I wouldn't mind if this fails or succeeds just that it would act
fail/succeed consistently between the device and the simulator.
Original comment by shai.almog
on 31 Jul 2013 at 6:24
I will have to look into each platform to see if it supports it. It looks like
this may be possible with iOS using an NSURLProtocol implementation (but I've
just started reading about this).
http://stackoverflow.com/questions/9301611/using-a-custom-nsurlprotocol-with-uiw
ebview-and-post-requests
For android I have run through some people asking about this, but haven't seen
a definitive solution yet.
E.g. https://groups.google.com/forum/#!topic/android-developers/INijIZ4F5G8
It will take some tinkering to find out one way or the other.
The JavaFX web view supports loading resources to a WebView from a Jar file.
It does this by using URL.toExternalForm() on the specific resource. But it is
able to correctly load sub-resources in the jar's child directories (e.g. if
images are in a subpath of the displayed page in the jar file. This tells us
that *at least* it will be possible to create this behaviour in the simulator.
I haven't even touched a Windows phone yet so I don't know where to begin on
there.
Original comment by st...@weblite.ca
on 31 Jul 2013 at 11:05
This seems like a bit too much effort. Maybe a better solution is to just
seamlessly unpack the resource the first time it is shown into a temporary
folder and just work from there?
This should be reasonably portable and require absolutely no change to our
build scripts. The only concern I have here is if a resource changes, I
wouldn't want to unpack the data every time the app runs.
Original comment by shai.almog
on 1 Aug 2013 at 5:01
Just did a bit of research regarding custom URL handlers. It looks like it
isn't that hard on iOS, Android, JavaSE, and WinPhone. Haven't found a way yet
on JavaME or BlackBerry.
Here are some links:
Android & JavaSE
Mentions using a Custom URLStreamHandlerFactory for loading images:
http://blog.wu-man.com/2012/10/androidimageloader-loading-images.html
setURLStreamHandlerFactory API docs
http://developer.android.com/reference/java/net/URL.html#setURLStreamHandlerFact
ory(java.net.URLStreamHandlerFactory)
More Discussion of Loading resources from a resource file using custom URL
stream handler
http://stackoverflow.com/questions/8938260/url-seturlstreamhandlerfactory
http://stackoverflow.com/questions/861500/url-to-load-resources-from-the-classpa
th-in-java
More on custom url stream handlers
http://www.unicon.net/node/776
Windows Phone 7 & 8
WebRequest Creator
http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.net.browser.
webrequestcreator(v=vs.105).aspx
(Looks like it can be used to register custom protocols)
iOS
Custom NSURLProtocol
http://stackoverflow.com/questions/9301611/using-a-custom-nsurlprotocol-with-uiw
ebview-and-post-requests
Java ME
Haven't found a way to make custom protocol handlers yet
Unpacking to a temp directory may work... I haven't tried loading any web pages
from any locations other than the main bundle on iOS yet... we'd want to make
sure we haven't traded one difficult problem for another one :)
Original comment by st...@weblite.ca
on 1 Aug 2013 at 6:24
Interesting... J2ME doesn't have a native browser so naturally you won't find
anything.
HTMLComponent has its own URL code which already supports loading from
resources.
Original comment by shai.almog
on 1 Aug 2013 at 9:57
Original issue reported on code.google.com by
st...@weblite.ca
on 29 Jul 2013 at 8:37Attachments: