Include headers in UNO for iOS

Hi,

i need help with UNO file and build iOS version. On build phase i have these messages:
(fuse version 0.29.0)

Building iOS app
/opt/fuse/xy/build/iOS/Debug/src/_root.QReaderImpl.mm:5:10: error: 'QRCodeReader.h' file not found with <angled> include; use "quotes" instead
/opt/fuse/xy/build/iOS/Debug/src/_root.QReaderImpl.mm:6:10: error: 'QRCodeReaderViewController.h' file not found with <angled> include; use "quotes" instead
/opt/fuse/xy/build/iOS/Debug/src/_root.QReaderImpl.mm:7:10: error: 'QReaderTask.h' file not found with <angled> include; use "quotes" instead
** BUILD FAILED **


The following build commands failed:
	CompileC build/xy.build/Release-iphoneos/xy.build/Objects-normal/armv7/_root.QReaderImpl.o src/_root.QReaderImpl.mm normal armv7 objective-c++ com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
(2.4s)

Build completed in 10.43 seconds

Uno file:

using Uno;
using Uno.Collections;
using Fuse.Scripting;
using Fuse.Reactive;
using Fuse;
using Uno.Compiler.ExportTargetInterop;
using Uno.Threading;

public class QReader : NativeModule {
	public QReader () {
		// Add Load function to load image as a texture
		AddMember(new NativePromise<string, string>("scan", (FutureFactory<string>)Scan,null));
	}

	static Future<string> Scan(object[] args)
	{
		//var path = Uno.IO.Path.Combine(Uno.IO.Directory.GetUserDirectory(Uno.IO.UserDirectory.Data), "temp.jpg");
			return QReaderImpl.Scan();
	}
}

[ForeignInclude(Language.Java,
                "android.app.Activity",
                "android.content.Intent",
                "android.net.Uri",
                "android.os.Bundle",
				"com.google.android.gms.common.api.CommonStatusCodes",
				"com.fuse.qreader.BarcodeCaptureActivity",
				"com.google.android.gms.vision.barcode.Barcode")]
[Require("Gradle.Dependency.Compile","com.android.support:support-v4:23.0.1")]
[Require("Gradle.Dependency.Compile","com.google.android.gms:play-services-vision:9.2.1")]
[Require("Gradle.Dependency.Compile","com.android.support:design:23.0.1")]
[ForeignInclude(Language.ObjC, "QReaderTask.h", "QRCodeReaderViewController.h", "QRCodeReader.h")]
public class QReaderImpl
{
	static int RC_BARCODE_CAPTURE = 9001;

	static bool InProgress {
		get; set;
	}

	static Promise<string> FutureResult {
		get; set;
	}

	static extern(Android) Java.Object _intentListener;

	public static Future<string> Scan() {
		if (InProgress) {
			return null;
		}
		InProgress = true;
		if defined(Android) {
			 if (_intentListener == null)
				_intentListener = Init();
		}
		ScannerImpl();
		FutureResult = new Promise<string>();
		return FutureResult;
	}

	[Foreign(Language.Java)]
	static extern(Android) Java.Object Init()
	@{
	    com.fuse.Activity.ResultListener l = new com.fuse.Activity.ResultListener() {
	        @Override public boolean onResult(int requestCode, int resultCode, android.content.Intent data) {
	            return @{OnRecieved(int,int,Java.Object):Call(requestCode, resultCode, data)};
	        }
	    };
	    com.fuse.Activity.subscribeToResults(l);
	    return l;
	@}

	[Foreign(Language.Java)]
	static extern(Android) bool OnRecieved(int requestCode, int resultCode, Java.Object data)
	@{

						if (requestCode == @{RC_BARCODE_CAPTURE}&&resultCode == CommonStatusCodes.SUCCESS && data != null) {

										Barcode barcode = ((Intent)data).getParcelableExtra(BarcodeCaptureActivity.BarcodeObject);
										if(barcode.displayValue != ""){
													@{Picked(string):Call(barcode.displayValue)};
										}else{
														@{Cancelled():Call()};
										}
						}
						else {
										@{Cancelled():Call()};
						}

	    return (requestCode == @{RC_BARCODE_CAPTURE});
	@}

	static extern(!Mobile) void ScannerImpl () {
		throw new Fuse.Scripting.Error("Unsupported platform");
	}

	[Require("Gradle.Dependency.Compile","com.android.support:support-v4:23.0.1")]
	[Require("Gradle.Dependency.Compile","com.google.android.gms:play-services-vision:9.2.1")]
	[Require("Gradle.Dependency.Compile","com.android.support:design:23.0.1")]
	[Require("AndroidManifest.ApplicationElement", "<activity android:name=\"com.fuse.qreader.BarcodeCaptureActivity\" android:theme=\"@style/Theme.AppCompat\"></activity>")]
	[Require("AndroidManifest.RootElement", "<uses-feature android:name=\"android.hardware.camera\"/>")]
	[Require("AndroidManifest.RootElement", "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>")]
	[Require("AndroidManifest.RootElement", "<uses-permission android:name=\"android.permission.CAMERA\"/>")]
	[Foreign(Language.Java)]
	static extern(Android) void ScannerImpl ()
	@{
		Activity a = com.fuse.Activity.getRootActivity();
		// Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		Intent intent = new Intent(a, BarcodeCaptureActivity.class);
		a.startActivityForResult(intent, @{RC_BARCODE_CAPTURE});

	@}

	[Require("Entity","QReaderImpl.Cancelled()")]
	[Require("Entity","QReaderImpl.Picked(string)")]
	[Foreign(Language.ObjC)]
	static extern(iOS) void ScannerImpl ()
	@{
			QReaderTask *task = [[QReaderTask alloc] init];

			static QRCodeReaderViewController *vc = nil;
			static dispatch_once_t onceToken;

			UIViewController *uivc = [UIApplication sharedApplication].keyWindow.rootViewController;
			[task setUivc:uivc];

			dispatch_once(&onceToken, ^{
					QRCodeReader *reader = [QRCodeReader readerWithMetadataObjectTypes:@[AVMetadataObjectTypeQRCode,
                               AVMetadataObjectTypeUPCECode,
                               AVMetadataObjectTypeCode39Code,
                               AVMetadataObjectTypeCode39Mod43Code,
                               AVMetadataObjectTypeEAN13Code,
                               AVMetadataObjectTypeEAN8Code,
                               AVMetadataObjectTypeCode93Code,
                               AVMetadataObjectTypeCode128Code,
                               AVMetadataObjectTypePDF417Code,
                               AVMetadataObjectTypeAztecCode]];
					vc                   = [QRCodeReaderViewController readerWithCancelButtonTitle:@"Zrušit" codeReader:reader];
					vc.modalPresentationStyle = UIModalPresentationFormSheet;
			});

			vc.delegate = task;

			[uivc
				presentViewController:vc
				animated:YES
				completion:nil];
	@}

	public static void Cancelled () {
		InProgress = false;
		FutureResult.Reject(new Exception("User cancelled the qr scanner"));
	}

	public static void Picked (string result) {
		InProgress = false;
		FutureResult.Resolve(result);
	}

}
 

Because documentation for UNO is very wrong, it is hard for me investigate, what is incorrect

thnx

From a chat on Slack we have established that this may be a new issue on fuse 0.28.0 build works correctly

part of donald’s unoproj

"Packages": [
       "Fuse",
       "FuseJS"
 ],
 "Includes": [
   "Pages/*.uno",
   "Pages/*.ux",
   "Components/*.ux",
   "NativeSrc/QReaderTask.h:ObjCHeader:iOS",
   "NativeSrc/QReaderTask.mm:ObjCSource:iOS",
   "NativeSrc/QRCodeReader.h:ObjCHeader:iOS",
   "NativeSrc/QRCodeReader.mm:ObjCSource:iOS",
   "NativeSrc/QRCodeReaderDelegate.h:ObjCHeader:iOS",
   "NativeSrc/QRCodeReaderView.h:ObjCHeader:iOS",
   "NativeSrc/QRCodeReaderView.mm:ObjCSource:iOS",
   "NativeSrc/QRCodeReaderViewController.h:ObjCHeader:iOS",
   "NativeSrc/QRCodeReaderViewController.mm:ObjCSource:iOS", (edited)

Hi, do you have any news about this issue ?
Or, do you have some temporary workaround for this issue ?
Because today I do not have way how build iOS version with 0.29.0 version and your team will release already soon version 0.30.0
thnx

Hey Donald,

Have you verified that your include path is correct? I think the ForeignIncludes are relative to the project, so if your project contains "NativeSrc/QReaderTask.h:ObjCHeader:iOS" the include should be [ForeignInclude(Language.ObjC, "NativeSrc/QReaderTask.h")].

Hope that helps!