geplaatst door: Manneke
Hallo Scripters!

Ik ben sinds korte tijd in XCode gedoken. Deze wijze van programmeren is volledig nieuw voor me waardoor er uiteraard spelenderwijs wat vragen naar boven zijn gekomen. Ik heb al een app redelijk draaiende maar ik loop vast op het verwerken van arrays. Ik gebruik een iPod met een extern apparaat die barcodes kan scannen. Dit maakt het voor mij nog net wat ingewikkelder ;-)
Ik ben zelf programmeur in PHP, wat uiteraard een hele andere wereld is dan Objective-C, maar spelenderwijs probeer ik te leren.

Ik heb een script die doormiddel van het externe apparaat (Linea Pro) een barcode scant. Deze checkt in een database of deze barcode bekend is en bij een foutieve barcode geeft hij 2 beeps. Deze beeps doe ik op de volgende wijze:

int errorSound[]={1100,150,0,30,1100,150};
[linea playSound:100 beepData:errorSound length:sizeof(errorSound) error:nil];

(Je moet de array 'errorSound' per 2 getallen lezen. Eerste is toonhoogte, 2e is de duur van de toon. Dit zijn dus 2 beeps met korte tussenpauze.)

Hij speelt de beep succesvol af. Echter wanneer ik van view schakel, en dan terug kom in deze view dan voegt hij nogmaals 3 beeps toe aan de al bestaande array met beeps.

Hoe kan ik de array errorSound[] vooraf leegmaken bij het openen van de view of dit op een andere wijze oplossen? Ik heb al gekeken met mutable array, dat heb ik helaas ook niet werkend gekregen.

Bedankt alvast!

Vraag omtrent Arrays; 'verwijderen' van array
3 juli 2012 - 13:11    reactie #1
geplaatst door: Manneke
Handig als extra info, dit is de wijze waarop het playsound command werkt

- (BOOL)
playSound:  (int)   //volume
beepData: (int *)  //data
length: (int) //length
error: (NSError **) //error

Makes Linea plays a sound using the built-in speaker.
Note:A sample beep containing of 2 tones, each with 400ms duration, first one 2000Hz and second - 5000Hz will look int beepData[]={2000,400,5000,400} Parameters:

volume = controls the volume (0-100). Currently have no effect
data = an array of integer values specifying pairs of tone(Hz) and duration(ms).
length = length in bytes of beepData array
error = pointer to NSError object, where error information is stored in case function fails. You can pass nil if you don't want that information

Returns: TRUE if function succeeded, FALSE otherwise

Vraag omtrent Arrays; 'verwijderen' van array
3 juli 2012 - 13:47    reactie #2
geplaatst door: Manneke
   NSMutableArray *errorSound = [[NSMutableArray alloc] init];
   NSNumber *waarde1 = [NSNumber numberWithInt:1100];
   NSNumber *waarde2 = [NSNumber numberWithInt:0];
   NSNumber *waarde3 = [NSNumber numberWithInt:150];
   NSNumber *waarde4 = [NSNumber numberWithInt:30];
   [errorSound addObject:waarde1];
   [errorSound addObject:waarde3];
   [errorSound addObject:waarde2];
   [errorSound addObject:waarde4];
   [errorSound addObject:waarde1];
   [errorSound addObject:waarde3];
   [linea playSound:100 beepData:errorSound length:sizeof(errorSound) error:nil];

Omdat ik nog niet zo heel bekend ben met arrays is bovenstaande beetje omslachtig, maar hierop ontvang ik de volgende foutmelding op de linea regel:
Incompatible pointer types sending 'NSMutableArray *' to parameter of type 'int *'

Ik hoop dat iemand dit kan uitleggen. Naar mijn idee (let op: nieuweling) maak ik een mutablearray aan en voeg ik daar int waardes aan toe. Ik hoop dat iemand kan vertellen waar ik fout denk.

Vraag omtrent Arrays; 'verwijderen' van array
3 juli 2012 - 15:41    reactie #3
geplaatst door: Willemien
De tweede parameter van playSound:beepData:length:error: moet een array van integers zijn, niet een pointer naar een object van class NSMutableArray, dat zijn twee heel verschillende dingen.

Weet je zeker dat er extra beeps aan de array worden toegevoegd? Of wordt de method waarin de beeps worden gegeven te vaak aangeroepen? Of komen de extra beeps ergens anders vandaan?

Leuke barcodelezer maar hoe debug je je programma, kan je de simulator gebruiken?

p.s. Je noemt jezelf programmeur en stelt de vraag aan scripters. Volgens mij is dat verkeerd om.  :wink:

Vraag omtrent Arrays; 'verwijderen' van array
3 juli 2012 - 15:53    reactie #4
geplaatst door: Manneke
Haha daar heb je een punt! Correctie; Hallo Programmeurs!

De reader is inderdaad een leuk apparaat, deze wordt ook gebruikt in diverse apple stores door het personeel. Debuggen is inderdaad wat pittiger, en zonder developper licentie is dat ook niet mogelijk. Ik heb daarom een betaald account zodat ik hem op een iPod Touch kan testen (daar komt de applicatie ook op te draaien).

Je legt ook meteen de vinger op de zere plek, want ik moet nog érg wennen aan het hele 'pointer' verhaal. Ik wist dat ik met int arrayNaam[]={} een simpele array aanmaak, maar dacht dat een mutablearray beetje hetzelfde zou doen... maar helaas ;) dat moet ik nog even doorkrijgen.

Ik heb de .m file aangepast:

-(void)errSound{
int errorSound[]={1100,150,0,30,1100,150};
[linea playSound:100 beepData:errorSound length:sizeof(errorSound) error:nil];
}

En deze roep ik dan vanuit de scanfunctie in dezelfde .m file aan doormiddel van:

NSLog(@"geen artikel gevonden");
[self errSound];

De method 'errSound' wordt maar 1x aangeroepen, want de NSLog komt maar 1x voor.

Ik heb de applicatie ontworpen met meerdere views. De eerste is een hoofdmenu waarmee je omschakelt naar de view waar dit script in draait (we noemen hem even hoofdmenu.m). Wanneer je voor de eerste keer naar de 2e view gaat (scanpagina.m) dan geeft hij netjes de 2 beeps zoals het hoort.

Keer je nu terug naar de eerste view (hoofdmenu.m) en daarna weer naar de 2e pagina (scanpagina.m) dan zal hij 4 beeps geven in plaats van de 2. Het lijkt wel alsof hij de "int errorSound[]" blijft onthouden als hij van view wisselt, en dan opnieuw de beeps toevoegt aan de errorSound array.

Een oplossing zou kunnen zijn om in de [Linea] regel zelf de beeps aan te roepen,
maar ik hoop dat jij me dan kan leren hoe ik dit in de regel zelf kan toepassen.

(Bewerkt door Manneke om 16:55, 3-07-2012)

(Bewerkt door Manneke om 16:59, 3-07-2012)

Vraag omtrent Arrays; 'verwijderen' van array
4 juli 2012 - 00:30    reactie #5
geplaatst door: Willemien
Wat gebeurt er als je het volgende doet:

NSLog(@"geen artikel gevonden");
[self errSound];
[self errSound];
[self errSound];

Krijg je dan 6 beeps?
en zet eens NSLog met sizeof(errorSound) in errSound.

Ik denk niet dat het probleem in de array zit en dat je het ergens anders moet zoeken. Ik heb geen verstand van iOS en ken de Linea SDK niet maar het lijkt alsof elke keer als je naar de 2e view gaat er een view bij komt en alle 2e views reageren op het scannen en beeps geven. Je zou dan ook die "geen artikel gevonden" meerdere malen moeten krijgen. Een slag in de lucht: roep je [linea addDelegate:…] en [linea removeDelegate:…] even vaak aan?

Vraag omtrent Arrays; 'verwijderen' van array
4 juli 2012 - 09:02    reactie #6
geplaatst door: Manneke
Hallo Willemien,

Je zit inderdaad in de goede richting, dat ik zeker!
Ik heb in de functie 'barcodeData' ook een NSLog gezet, deze functie verwerkt de barcode scan gegevens. Deze NSLog wordt ook 2x aangeroepen!

Dus het is inderdaad dat hij zaken 2 maal aanroept.

Die functie ziet er uit als volgt:


-(void)barcodeData:(NSString *) barcode type:(int) type{
   NSLog(@"Barcode scanned");
   myScannedCode=barcode; // myScannedCode is een in .h gedefinieerde NSString. Die lees ik in doScan weer uit.
   [self doScan]; // roep de database check functie op, waar de beeps ook in zitten.
}

Alles lijkt er inderdaad op dat dingen dubbel geladen worden.
Ik heb nu ook de removeDelegate in de viewDidUnload gezet.

Welke zaken kunnen veroorzaken dat methods dubbel worden aangeroepen?

Om te schakelen van view gebruik ik het volgende (wie weet maak ik daar een grove beginnersfout ;-) ):


-(IBAction)toMenu{
   ViewBasedViewSwitchController *toMenu = [[ViewBasedSwitchController alloc] initWithNibName:nil bundle:nil];
   [toMenu setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
   [self presentModalViewControllor:toMenu animated:YES];
}

ViewBasedViewSwitchController is hier de naam van het 'hoofdmenu'. Die naam komt uit een tutorial, vandaar ;-).

Vraag omtrent Arrays; 'verwijderen' van array
4 juli 2012 - 13:28    reactie #7
geplaatst door: Manneke
Het lijkt er op dat ik een fix heb voor het probleem.
De wijze waarop ik switchte van views leek het probleem te geven (zoals Willemien al dacht).

Ik heb deze wijze gewijzigd.

In de appdeligate.h:

-(void)switchView:(UIView *)view1 toView:(UIView *)view2;

In de appdeligate.m:

-(void)switchView:(UIView *)view1 toView:(UIView *)view2{
   NSLog(@"Do de switch");
   [UIView beginAnimations:@"animation" context:nil];
   [UIView setAnimationDuration:0.75];
   [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.window cache:YES];
   [view1 removeFromSuperview];
   [window addSubview:view2];
   [UIView commitAnimations];
}

En dan kan ik in elke view van View wisselen doormiddel van:

-(IBAction)toMenu:(id)sender{
   counter=1;
 ViewBasedViewSwitchAppDelegate *delegate = (ViewBasedViewSwitchAppDelegate *)[[UIApplication sharedApplication] delegate];
   ViewBasedViewSwitchViewController *hoofdMenupage = [[ViewBasedViewSwitchViewController alloc] initWithNibName:@"ViewBasedViewSwitchViewController" bundle:nil];
   [delegate switchView:self.view toView:hoofdMenupage.view];
}

Helaas loop ik nu tegen het punt aan dat de geleende Linea Pro problemen lijkt te hebben (geeft geen barcode reading meer, hij gaat niet aan) maar doormiddel van een textfield kan ik een fictieve barcode read doen die goed gaat :)

Deze wijziging had ik gevonden in een tutorial op youtube;

Handig voor de beginnende XCoder die dit topic bezoekt ;-)

Vraag omtrent Arrays; 'verwijderen' van array
4 juli 2012 - 14:02    reactie #8
geplaatst door: Manneke
Kleine voetnoot;

Bij het gebruik van deze wijze van View switchen, moet je deze regel toevoegen aan je .m bestanden:


- (void)viewDidLoad {
 self.view.frame = [[UIScreen mainScreen] applicationFrame];
}

Anders valt je view onder de statusbalk van IOS :)

(Bewerkt door Manneke om 15:03, 4-07-2012)