How Java Resources map to iOS Resources

What are Java Resources

Java resources are data files that are packaged with Java applications and libraries. These resources are loaded at runtime either Class.getResource(String name), which returns a java.net.URL, or Class.getResourceAsStream(String name), which returns a java.io.InputStream. The getResourceAsStream() method is normally used when a resource is expected to be available, since it throws an IOException if it isn't. The getResource() method returns null if the resource isn't present, so it's useful to test for optional resources.

Resource Names and Paths

J2ObjC locates resources by looking in the application's main bundle ([NSBundle mainBundle]), using the resource's relative or absolute path:

Relative Paths

The preferred method of specifying resource paths is by using relative paths. Relative paths do not start with a forward slash ('/'). When reading a resource with a relative path, the class's package name is modified, changing the periods ('.') in the package name to forward slashes ('/'), then the relative path specified in the Class.getResource(String name) or Class.getResourceAsStream(String name) method call is appended to the package path.

For example, if an app has a foo.bar.Mumble class, the base path for all resources relative to classes in that package is /foo/bar. When Mumble.class.getResource("oops/error.jpg") is invoked, oops/error.jpg is appended to the package's path, so its full resource path is /foo/bar/oops/error.jpg.

Absolute Paths

A resource can also be accessed using an absolute path by starting the resource's name with a forward slash ('/'). Package names are ignored, so J2ObjC locates absolute paths in the application's main bundle using the paths exactly as specified in the Class.getResource(String name) or Class.getResourceAsStream(String name) references in the application's Java sources. In the above example, Mumble.class.getResource("/oops/error.jpg") has a full resource path of /oops/error.jpg, ignoring the foo.bar package name.

Adding Resources to an iOS App

To add resource files to an iOS app in Xcode, open the build target's Build Phases tab. Then:

  • Click the + icon (under the General tab) and select New Copy Files Phase.
  • Select "Resources" as the Destination (not Java Resources).
  • Specify the directory for the resource(s).
  • Select + and add the file(s) to its list.

Regardless of whether relative or absolute resource paths are used, each resource directory requires a separate Copy Files build phase in an Xcode build.

Example

The JreEmulation project has a "JRE JUnit Tests" app that runs that library's unit tests. Select that target's Build Phases to see several Copy Files phases, one each for every relative path used by its resources. Here, ClassTest.java loads the same resource using first an absolute path, and then a relative path. The test's resource is included using this Copy Files build phase:

Xcode resources