0

I have successfully created connection to Apple MFi printer, but I'm failed to have NSOutputStream to write to the printer because delegate did not called.

Here is my LibPrint.h:-

#import <Foundation/Foundation.h>
#import <ExternalAccessory/ExternalAccessory.h>
#import "FlashRuntimeExtensions.h"

@interface LibPrint : NSObject <NSStreamDelegate>

- (void)printR;
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent;

@end

// C interface
FREObject fncPrintR(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]);

LibPrint.m:-

#import "LibPrint.h"

@interface LibPrint ()

@property (nonatomic, strong) EASession *easPrinter;
@property (nonatomic, strong) NSData *datPrintData;

@end

@implementation LibPrint

FREContext eventContext;
LibPrint *AirInAppRefToSelf;

#pragma mark - NSObject
-(id)init
{
    self = [super init];
    if (self)
    {
        AirInAppRefToSelf = self;
        self.easPrinter = nil;
        self.datPrintData = nil;
    }
    return self;
}

-(void)dealloc
{
    self.easPrinter = nil;
    self.datPrintData = nil;
    AirInAppRefToSelf = nil;
}

#pragma mark - ANE setup
void LibPrintExtContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet)
{
    *numFunctionsToTest = 1;
    FRENamedFunction* func = (FRENamedFunction*) malloc(sizeof(FRENamedFunction) * *numFunctionsToTest);
    func[0].name = (const uint8_t*) "printR";
    func[0].functionData = NULL;
    func[0].function = &fncPrintR;
    *functionsToSet = func;
    eventContext = ctx;
    if ((LibPrint*) AirInAppRefToSelf == nil)
    {
        AirInAppRefToSelf = [[LibPrint alloc] init];
    }
}

void LibPrintContextFinalizer(FREContext ctx) { }

void LibPrintExtensionInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet)
{
    *extDataToSet = NULL;
    *ctxInitializerToSet = &LibPrintExtContextInitializer;
    *ctxFinalizerToSet = &LibPrintContextFinalizer;
}

void LibPrintFinalizer(void* extData) { }

#pragma mark - C interface
FREObject fncPrintR(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])
{
    FREObject result = NULL;

    if ([AirInAppRefToSelf datPrintData] != nil) {
        [AirInAppRefToSelf setDatPrintData:nil];
    }
    // Retrieve message
    NSData *ldatPrintData = toNSDataByteArray(argv[0]);
    [AirInAppRefToSelf setDatPrintData:ldatPrintData];
    [(LibPrint*) AirInAppRefToSelf printR];

    return result;
}

- (void)printR
{
    BOOL lblnConnected = false;
    BOOL lblnFound = false;
    NSArray *accessories = [EAAccessoryManager sharedAccessoryManager].connectedAccessories;
    for (EAAccessory *accessory in accessories)
    {
        if (accessory.connected)
        {
            lblnConnected = true;
            for (NSString *protocol in accessory.protocolStrings)
            {
                if ([protocol isEqualToString:@"jp.star-m.starpro"])
                {
                    lblnFound = true;
                    [self setEasPrinter:[[EASession alloc] initWithAccessory:accessory forProtocol:protocol]];
                    [[self easPrinter].outputStream setDelegate:self];
                    [[self easPrinter].outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
                    [[self easPrinter].outputStream open];
                }
            }
        }
    }
    FREDispatchStatusEventAsync(eventContext, (uint8_t*)"DEBUG_DATA", (uint8_t*) [[NSString stringWithFormat: @"connected: %s", lblnConnected ? "true" : "false"]  UTF8String]);
    FREDispatchStatusEventAsync(eventContext, (uint8_t*)"DEBUG_DATA", (uint8_t*) [[NSString stringWithFormat: @"found: %s", lblnFound ? "true" : "false"]  UTF8String]);
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
    FREDispatchStatusEventAsync(eventContext, (uint8_t*)"DEBUG_DATA", (uint8_t*) [@"NSStreamDelegate"  UTF8String]);
    switch (streamEvent)
    {
        case NSStreamEventNone:
        {
            break;
        }
        case NSStreamEventOpenCompleted:
        {
            break;
        }
        case NSStreamEventHasBytesAvailable:
        {
            break;
        }
        case NSStreamEventHasSpaceAvailable:
        {
            FREDispatchStatusEventAsync(eventContext, (uint8_t*)"DEBUG_DATA", (uint8_t*) [@"NSStreamEventHasSpaceAvailable"  UTF8String]);
            NSInteger len = [[self easPrinter].outputStream write:[[self datPrintData] bytes] maxLength:[[self datPrintData] length]];
            FREDispatchStatusEventAsync(eventContext, (uint8_t*)"DEBUG_DATA", (uint8_t*) [[NSString stringWithFormat: @"data len: %ld, returned len: %ld", [[self datPrintData] length], len]  UTF8String]);
            break;
        }
        case NSStreamEventErrorOccurred:
        {
            break;
        }
        case NSStreamEventEndEncountered:
        {
            break;
        }
    }
}

NSData *toNSDataByteArray(FREObject *ba)
{
    FREByteArray byteArray;
    FREAcquireByteArray(ba, &byteArray);
    NSData *d = [NSData dataWithBytes:(void *)byteArray.bytes length:(NSUInteger)byteArray.length];
    FREReleaseByteArray(ba);
    return d;
}

@end

I have printer connected good, but the delegate method [- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent] never run. I guess maybe the currentRunLoop issue, I tried to change it to mainRunLoop, but still no clue. Please help! Thx in advanced.

Michael
  • 3,776
  • 1
  • 16
  • 27
Season W.
  • 11
  • 1
  • 3

1 Answers1

0
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

Instead of using [NSRunLoop currentRunLoop] I changed it to [NSRunLoop mainRunLoop].

set inputStrean in the same way:

[[self easPrinter].inputStream setDelegate:self];
[[self easPrinter].inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[[self easPrinter].inputStream open];
ChenYilong
  • 8,543
  • 9
  • 56
  • 84
  • Like I mentioned in my last paragraph, I have tried mainRunLoop too with no clue. And actually I have also tried inputStream with mainRunLoop, but still delegate not calling. Any more solution? – Season W. Aug 22 '15 at 00:19