Infos zu einer App: Version – Sprache

Eine App für eine breite Kundschaft zu entwickeln bedeutet auch, eine Vielzahl an Variationen von Problemmöglichkeiten zu kreieren. Wenn dann wirklich ein Problem auftritt, möchte man vom Kunden möglichst genau dessen Rahmenbediengungen kennen.

Dazu zählt bei einer iOS App insbesondere:

Quelle:

Welche App hat er genau genutzt?

Version:

Welche Version der App wurde verwendet? Wurde evtl. eine alte Version genutzt und ein reines Update würde helfen?

Sprache:

Welche Sprache ist eingestellt? Kommt das Problem evtl. von einem Übersetzungsfehler / einer fehlenden Übersetzung?

iOS Version:

Apple verhindert zwar recht gut, Funktionen zu verwenden, die in bestimmten iOS Versionen noch nicht oder nicht mehr verfügbar sind, nichts desto trotz, ist es bei Fehlern wichtig, zu wissen, welche iOS Version verwendet wird.

Die meisten der Informationen sind über [[NSBundle mainbundle] infoDictionary] erreichbar:

App Identifier: [[NSBundle mainBundle] infoDictionary] valueForKey:@“CFBundleIdentifier“]
App Version: [[NSBundle mainBundle] infoDictionary] valueForKey:@“CFBundleVersion“]

Die Sprache erhält man über: [[NSUserDefaults standardUserDefaults] objectForKey:@“AppleLanguages“] objectAtIndex:0]

Und zu guter letzt die iOS Version:
[[NSProcessInfo processInfo] operatingSystemVersionString] Hierbei ist darauf zu achten, dass im Simulator als Betriebssystem die OSX Version angegeben wird.

Mit den aufgeführten Angaben lässt sich schon recht genau das technische Umfeld des Nutzers eingrenzen und diese Informationen können automatisch beispielsweise in einer E-Mail angehängt werden.

Dabei bietet es sich an, die ankommenden E-Mails automatisch in ein Ticket System laufen zu lassen um auch keine Meldung zu vergessen. Als praktisch hat sich hierbei die OpenSource Ticket Verwaltung OTRS erwiesen. Auch für den professionellen Einsatz lohnt sich das System, da hinter den Entwicklern eine Firma steckt, die auch professionellen Support anbietet und Unterstützung bei der Umsetzung anbieten kann.

iPhone ADHoc build save to disk problem

Mit XCode können nicht nur Apps an den Apple App Store geschickt werden, registrierte Entwickler können auch an registrierte iOS Devices so genannte ADHoc Builds verteilen.

Dabei wird die Datei vom Ersteller signiert und dann lauffähig. Wie das ganze erledigt werden kann, habe ich in diesem Artikel beschrieben: ios-betabuilder-version-1-5-released. (Der BetaBuilder ist mittlerweile übrigens im MacStore erhältlich).

Was nun wenn es bei dem beschriebenen Vorgehen Probleme gibt? Beispielsweise kann es vorkommen, dass der Organizer bei dem Klick auf „Save to disk“ einfach nicht reagiert, ohne Fehlermeldung etc. Ein Blick in die logs mittels:

tail -f /var/log/system.log

bringt ein

header check failed

um Vorschein.

Mögliche Lösungen:

– „Project clean“ und neu builden

– XCode neu starten

– Rechner neu starten

– XCode neu installieren, Projekt cleanen, Projekt builden

Icon specified in the Info.plist not found under the top level app wrapper: Icon.png

Kleiner Fehler, große Wirkung, wer beim Submitten einer App an Apple die Fehlermeldung erhält:

Icon specified in the Info.plist not found under the top level app wrapper: Icon.png

Darf sich erstmal freuen, die Fehlermeldung ist schwer zu beheben.

Im einfachsten Fall hat man wirklich vergessen, das Icon.png in das Projekt zu legen. Es ist darauf zu achten, dass das Icon bestimmte Kriterien erfüllen muss (nachzulesen unter: http://developer.apple.com/library/ios/#qa/qa2010/qa1686.html)

Wichtig, die Icon File muss im Root des Projektes liegen und die Groß- und Kleinschreibung muss beachtet werden. Es kann helfen, das Projekt komplett aufzuräumen über:

Build -> Clean All Targets

Zusätzlich kann man nach dem cleanen noch die Icons alle umbenennen z.B. in bIcon.png und dann wieder zurück nach Icon.png benennen. Danach wie gehabt

Build -> Build and archive

An Apple senden

Je nachdem, ob man eine iPad App erstellt gibt es folgende möglichen Icon Variationen die in der Info.plist Datei hinterlegt werden:

  • Icon.png (57×57px – iPhone und iPod Touch)
  • Icon@2x.png (114×114 – iPhone 4 Retina Display)
  • Icon-72.png (72×72 – iPad)
  • Icon-Small.png (29×29 – Settings app und Suchergebnisse auf iPhone und iPod Touch)
  • Icon-Small@2x.png (58×58 – Settings app und Suchergebnisse auf iPhone 4)
  • Icon-Small-50.png (50×50 – Suchergebnisse auf iPad)

 

Paypal iOS SDK

PayPal iphone / iOS SDK

PayPal iphone / iOS SDK

In der aktuellen Diskussion über die Abo-Gebühren von Apple, die inApp Beteiligungen die verlangt werden, geht voll unter das es auch noch andere Bezahlmöglichkeiten gibt.

Unter anderem bietet PayPal ein eigenes iPhone / iOS SDK an.

Dieses kann in jede App eingebunden werden und den Bezahlvorgang für Inhalte übernehmen. Beträge, Rechnungsposten, Steuer / Versandgebühren sind dabei sehr gut einstellbar. Im Fall einer erfolgreichen Zahlung erhält man von PayPal eine PayPal-Transactions-ID, womit der jeder Bezahlvorgang eindeutig ist.

Eingebunden wird das SDK sehr einfach: Downloaden, Add existing Files -> die *.a Datei und alle .h Dateien auswählen und importieren.

In dem Viewcontroller, in dem der Bezahlvorgang dann vonstatten gehen soll folgende include Anweisung:

#import „PayPal.h“

weitere Schritte können in der Doku von Paypal entnommen werden.

Was nicht ind er Dokumentation erwähnt ist: um das SDK nutzen zu können, bedarf es auch einer xml Lib. Wenn diese nicht vorhanden ist, bekommt man Fehlermeldungen im folgenden Stil:

„_xmlNodeListGetString“, referenced from:

-[ap_ReceiverIdentifier deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_Address deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_AddressList deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_CurrencyCodeList deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_CurrencyList deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_CurrencyConversionList deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_CurrencyConversionTable deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_DisplayOptions deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

-[ap_ErrorList deserializeElementsFromNode:] in libPayPalMEP.a(ap.o)

usw.

Dieses kann verhindert werden, indem man die libxml2.dylib als existing Framework einbettet / hinzufügt.

GPS Distanz von Nutzer zu Punkt bestimmen

Um Die Distanz eines iPhone Users zu einem bestimmten Punkt zu bekommen, kann man die CLLLocation Methode getDistanceFrom wunderbar nutzen.
Vorraussetzung ist die Position des Gerätes. In der Methode

– (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation

kann dann folgender Codeschnipsel genutzt werden:

// hier die gewünschten GPS Koordinaten eingeben, die Beispieldaten sind von der Infinity Loop
CLLocation *DestinationLocation = [[CLLocation alloc]initWithLatitude:37.3307060 longitude:-122.0414486];

//Distanz in m berechnen
double dist = [newLocation  distanceFromLocation:festplatzlocation];

Um zu erkennen, ob der Nutzer innerhalb eines bestimmten Radiusses um einen Punkt ist, kann man eine maxdist definieren und danach darauf prüfen.

double maxdist = 3500;

if(dist<maxdist){

NSLog(@“kleiner“);
NSString *Distanzstring = [[NSStringalloc]initWithFormat:@“Distanz: %g (m)“,dist];
UIAlertView *alert = [[UIAlertViewalloc] initWithTitle:nilmessage:Distanzstring delegate:selfcancelButtonTitle:@“OK“otherButtonTitles:nil]; [alert show];
[alert release];
}else {
NSLog(@“grösser“);
}

Deprecated ist die folgende Methode / Bestimmung der Distanz

//double dist = [newLocation getDistanceFrom:festplatzlocation] / 1000;

Fertig ist eine schöne und einfache Möglichkeit, die position des Nutzer zu verwenden.

(Corelocation.Framework muss natürlich in das Projekt eingebunden sein)

Xcode Custom Back Button Action

Wer in seiner iPhone / iPad App eine Navigation-Bar nutzt, wird vllt. irgendwann an den Punkt gelangen, an dem er, aus welchen Gründen auch immer, eigene Aktionen bei Betätigung des BackButtons durchführen möchte.

Sei es, dass Speicher sofort freigegeben werden soll, eine Audio-File sofort gestoppt oder Meldungen an den Nutzer ausgegeben werden sollen. Hierzu ist eine mögliche Lösung, den vorhandenen BackButton durch einen einen eigenen zu ersetzen.

Dieser Button führt bei Touch dann eine Methode aus, in der die eigenen Anweisungen stehen, abgeschlossen durch die Anweisung, das aktuelle Element aus dem NavigationStack zu entfernen (pop).

Einziges „Problem“ ist das Layout des Buttons, diesen wie einen Back Button erscheinen zu lassen, ermöglicht das Framwork three20. Folgender Codeausschnitt veranschaulicht die Vorgehensweise:

-(void) goBack
{
//Write your custommethods
NSlog(„hello custom Back Button“);
//Go back
[self.navigationControllerpopViewControllerAnimated:YES];
}

-(id) initWithName: (NSString*)name initwithBackround:(NSString*)backround {

// … Stuff

//Create the custom back button

TTButton *backButtonView = [TTButtonbuttonWithStyle:@“toolbarBackButton:“title:@“Back“];

[backButtonView addTarget:selfaction:@selector(goBack) forControlEvents:UIControlEventTouchUpInside];

[backButtonView sizeToFit];

UIBarButtonItem *backButton = [[UIBarButtonItemalloc] initWithCustomView:backButtonView];

self.navigationItem.leftBarButtonItem = backButton;

[backButton release];

// Stuff

}

cell.image deprecated use setImage

Wer mit einer UITableView arbeitet, wird auch UITableViewCell nutzen. Bei einer TableViewCell kann in der default Zelle ein Bild (UIImage) gesetzt werden.
Auf den ersten Blick nutzt man einfach

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIImage *theimage = [UIImage imageNamed:@"web.jpg"];
cell.image = webimage;

Dies führt aber zu der Fehlermeldung:

„warning: ’setImage:‘ is deprecated (declared at …“

Lösung:

[cell.imageView setImage:[UIImage imageNamed:@"web.jpg"]];

Der Beitrag passt thematisch zu:

https://www.alexanderjaeger.de/cell-text-deprecated-use-cell-textlabel-text/

UITableView

UITableView

UITableView

UITableView ist ein mächtiges Werkzeug zur Darstellung und Verarbeitung von Informationen. Meistens ist die Anwendung, eine View, ein UITableView in dem eine Reihe von Informationen angezeigt werden. Diese Informationen haben dann jeweils unterschiedliche Actions.

Doch nicht immer trifft dieser UseCase ein, bzw. eine Anpassung der UITableViews ist notwendig. Daher wird hier nach und nach eine Sammlung an Tweaks, Tipps und Kniffen rund um UITableView gesammelt werden.

Hier ein paar Tweaks zum Thema UITableView:

Hintergrund Farbe der ganzen TableView ändern

myTableView.backgroundColor = [UIColor redColor];

Mehrere UITableViews in einer View

Wenn in einer UIView mehrere UITableViews geführt werden, so ist es möglicherweise notwendig, jeder TableView eine unterschiedliche ANzahl an Rows zu geben, dies kann folgendermaßen umgesetzt werden:

(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.myTableView1) {
return 2;
} else if (tableView == self.myTableView2) {
return 3;
} else {
// wird nie erreicht
}
}

Performancetuning

Hier findet man ne coole Möglichkeit, die Höhe einer Zeile performant zu ändern:

http://iphoneincubator.com/blog/windows-views/the-right-way-to-set-the-height-of-tableviewcells

Links zum Thema

http://www.iphonedevsdk.com/forum/iphone-sdk-development/26739-embed-uitableview-within-uiview.html

http://chris-software.com/index.php/dev-center/tables/

http://pessoal.org/blog/2009/02/25/customizing-the-background-border-colors-of-a-uitableview/

http://blogs.remobjects.com/blogs/mh/2009/04/11/displaying_variably_sized_text_cells_in_

UIButton Text ändern

Der UIButton im iPhone SDK Framwork lässt es zu, den Text je nach „Status“ zu ändern.

[myUIButton setTitle:@“Text1″ forState:UIControlStateNormal];
[myUIButton setTitle:@“Text2″ forState:UIControlStateHighlighted];
[myUIButton setTitle:@“Text3″ forState:UIControlStateSelected];

Natürlich können auch bei allen drei der gleiche Text genutzt werden, um den UIButton wie ein UILabel je nach Content zu benennen.

Der Button muss dazu natürlich als IBOutlet deklariert werden und mit dem entsprechenden UIViewcontroller @synthesize werden.

.h File

@property (nonatomic, retain) IBOutlet UIButton *myUIButton;

.m File

@synthesize myUIButton

Im Interfacebuilder muss das Outlet mit dem Button verbunden werden.

Links zum Thema UIButton:

http://chris-software.com/index.php/dev-center/creating-a-nice-glass-buttons/