Einige gesammelte Code Schnipsel und Codezeilen z.B. Shell-Scripte, Objective-C, oder Ähnliches.
Shell: Reset des USB-Subsystems
Ist mir persönlich jetzt schon mehrfach passiert, das das USB-Subsystem nicht mehr funktioniert hat. Sprich, bestimmte Festplatten wurden nicht mehr registriert beim einstecken oder bestimmte Smartphones. Man kann jedoch im Betrieb das USB zurücksetzen. Ein wenig Vorsicht ist aber geboten… denn die Tastatur und Maus hängt auch am USB wie der Teilweise berichtet. Wenn man das also runterfährt kann man seine Maschine nicht mehr steuern.
Man kann dennoch einfach die USB-Kernelextension ausknipsen und wieder an. Am besten startet man das Anschalten automatisch nach paar Sekunden, dann muss man sich nicht mühevoll auf die eigene Kiste einloggen. Ich hab die Codezeilen vom Teilweise mal etwas gepimp’ed. (bash-Script als restartSubsystemUsb.txt laden).
#!/bin/sh # # Script to restart the USB subsystem by unloading and reloading the # USB kernel extension which drives the USB system components. # This is useful if you have unresponding USB ports or devices # which are no longer correctly registered in the USB system # after some weird errors happened and you don't feel like restating # your whole machine just for this to be fixed. # if (( $EUID != 0 )); then echo "PLEASE RUN AS ROOT." exit fi echo "" echo "RESTARTING USB SUBSYSTEM NOW..." sleep 2 echo "SHUTDOWN..." sleep 2 # shutting down here echo "TIME: `date`" kextunload -b com.apple.driver.AppleUSBEHCI echo "TIME: `date`" echo "WAITING 20 SECONDS..." sleep 20 echo "RESTART..." # rebooting here echo "TIME: `date`" kextload -b com.apple.driver.AppleUSBEHCI echo "TIME: `date`" echo "DONE" echo ""
Man bekommt dann ungefähr sowas hier als Output, während alle Geräte, auch die Bluetoothgeräte (wie Trackpad) kurzzeitig ihre Verbindung verlieren.
RESTARTING USB SUBSYSTEM NOW...
SHUTDOWN...
TIME: Di 16 Sep 2014 10:52:19 CEST
(kernel) Can't unload kext com.apple.driver.AppleUSBEHCI; classes have instances:
(kernel) Kext com.apple.driver.AppleUSBEHCI class AppleEHCIIsochTransferDescriptor has 168 instances.
(kernel) Kext com.apple.driver.AppleUSBEHCI class AppleEHCIIsochEndpoint has 5 instances.
Failed to unload com.apple.driver.AppleUSBEHCI - (libkern/kext) kext is in use or retained (cannot unload).
TIME: Di 16 Sep 2014 10:52:20 CEST
WAITING 20 SECONDS...
RESTART...
TIME: Di 16 Sep 2014 10:52:40 CEST
TIME: Di 16 Sep 2014 10:52:40 CEST
DONE
Objective-C: iOS 7/iOS 8 Transition von iOS 6
Th best 2 lines of code for the transition you will ever find:
myViewController.edgesForExtendedLayout = UIRectEdgeNone; rootNavigationController.navigationBar.translucent = NO; rootNavigationController.toolbar.translucent = NO;
Shell: Inkompatibilitäten von Steuercodes für Cursortasten in vi abstellen
Wenn man sich per ssh auf andere Machinen einloggt, und per vi doch mal was editieren will, hat man oftmals das Problem, dass die Steuersequenzbelegung der Cursortasten von der eigene Emulation mal wieder nicht kompatibel ist. Folge ist z.B. bei vi gerne mal, dass man im edit-mode bei Nutzung der Cursortasten dann A, B, C, D erzeugt und der Cursor wegspringt. Auch das Löschen mit Backspace funktioniert nicht richtig. Das kann man schnell beheben indem man im vi zuerst eingibt:
:set nocompatible
Oder aber man legt folgende Konfigurationsdatei für vi/vim im $HOME an:
.vimrc
mit dem folgenden Inhalt (man beachte wie ähnlich das zur Eingabe im vi ist):
set nocompatible
Das setzt einen Parameter bei jedem Start von vi. So wird das problem jedoch nur für den vi gelöst. Andere Kommandozeilentools leiden weiterhin. Deshalb alternativ kann man auch in dem eigenen Terminal Programm mal in den Settings wühlen und die default-Emulation mal ändern (da stehen oft so Sachen wie xterm-color16, ansi, vt100, linus, usw.). Sofern „linux“ verfügbar ist sollte man das mal nehmen. Wird aber meist erst aktiv nach einem Neustart des eingesetzten Terminal Programms.
Shell: Text to PDF von der Kommandozeile
Hiermit kann man von der Kommandozeile aus normalen Text in schön formatiertes PDF umleiten, mittels enscript
, das man widerum per MacPorts
installieren kann.
#!/bin/bash MOD_TIME_EPOCH=`stat -f %m $1` MOD_TIME_FMT=`date -r $MOD_TIME_EPOCH +'%a %e %b %Y @ %R %Z' | sed 's/ [ ]*/ /g'` FULL_NAME=`php -r "echo realpath('$1');"` mkdir -p $HOME/.enscript # Create temporary "fancy header" file for enscript. cat > $HOME/.enscript/tmp_txt2pdf.hdr <<EOF % -- code follows this line -- %Format: last_mod_timestr $MOD_TIME_FMT %Format: pagestr page \$V$%/$= %HeaderHeight: 30 %FooterHeight: 30 /Helvetica /helvetica-encoded MF /Helvetica-10-Regular /helvetica-encoded findfont 10 scalefont def /Helvetica-Bold /helvetica-bold-encoded MF /Helvetica-10-Bold /helvetica-bold-encoded findfont 10 scalefont def /new_marg 4 def /do_header { gsave Helvetica-10-Bold setfont d_footer_x d_footer_w add pagestr stringwidth pop sub new_marg sub d_footer_y 7 add moveto pagestr show Helvetica-10-Bold setfont d_footer_x new_marg add d_footer_y 7 add moveto last_mod_timestr show Helvetica-10-Bold setfont d_header_x d_header_w 2 div add fname stringwidth pop 2 div sub d_header_y 16 add moveto fname show grestore } def EOF enscript --encoding=latin1 --fancy-header=tmp_txt2pdf --word-wrap -p - "$FULL_NAME" | gs -q \ -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="$2" - rm -f $HOME/.enscript/tmp_txt2pdf.hdr
Shell: Lang laufende UNIX jobs mit Benachrichtigung
Folgende Codezeile hilft einem, das Ende eines Jobs nicht zu verpassen. Sobald der Task beendet wurde wird mittels tput bel
eine akustische Meldung ausgegeben und ein roter Badge an das Terminalicon im Dock gepackt.
make install && tput bel
Es geht auch noch eleganter, wenn man sich mittels des Ruby GEMS terminal-notifier
(bei GitHUB) im Message Center von OS X benachrichtigen lassen will.
terminal-notifier -message "Installation vom Terminal ist fertig!" -title "Terminal hat feddich!"
Shell: FileSharing & FTP-Server von der Konsole aus starten & stoppen
Grade wenn man mehrere Macs im Haus hat (z.B. auch als MediaServer), ist das folgende Kommando ganz praktisch, wenn man sich per SSH auf die Zielmaschine einklinken kann und dann ohne viel Aufwand mal eben FileSharing anknippsen kann. So muss man keinen Bildschirm anschließen und das Einstellungspanel für Sharing-Dienste anklicken.
# Zum Starten des FileSharing launchctl load -w /System/Library/LaunchDaemons/com.apple.AppleFileServer.plist # Zum Stoppen des FileSharing launchctl unload -w /System/Library/LaunchDaemons/com.apple.AppleFileServer.plist
Auf die gleiche Art kann man sich übrigens einen FTP-Serverdienst an- und ausschalten.
# Zum Starten des FTP-Server launchctl load -w /System/Library/LaunchDaemons/ftp.plist # Zum Stoppen des FTP-Server launchctl unload -w /System/Library/LaunchDaemons/ftp.plist
Objective-C: Richtiges escapen von values für URL-Parameter
Leider ist die Methode von NSString stringByAddingPercentEscapesUsingEncoding
nicht wirklich brauchbar für das escapen von Zeichen wie z.B. dem &,?,#
usw. daher nutze ich folgende Methoden für diese Arbeit.
// String encoden für Verwendung in URL als value NSString* newEncodeToPercentEscapeString(NSString *string) { return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef) string,NULL,(CFStringRef) @"!*'();:@&=+$,/?%#[]",kCFStringEncodingUTF8); } // String decoden NSString* newDecodeFromPercentEscapeString(NSString *string) { return (NSString *) CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,(CFStringRef) string, CFSTR(""), kCFStringEncodingUTF8); }
Aber Achtung der String kommt mit retaincount=1 zurück… man muss den also releasen wenn man fertig ist.
Objective-C: Autolayout im Übergang iOS 5 zu iOS 6
Apple hat mit iOS 6 eine ganze Menge verändert hinsichtlich der bisherigen Layoutfunktionen. U.a. damit sie die neue Displaygröße des iPhone 5 abbilden können. Nervig ist allerdings, dass man während des Übergangs nun für die ganz normale AutoRotation statt wie bisher einer jetzt bis zu fünf Methoden einbauen muss damit sich was dreht. Nämlich folgende:
/** * Im AppDelegate */ // NEWER IOS >= 6.x - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskAll; } /** * Im ViewController */ // OLDER IOS < 6.x - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } // NEWER IOS >= 6.x - (BOOL) shouldAutorotate { return YES; } // NEWER IOS >= 6.x - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } // NEWER IOS >= 6.x (OPTIONAL) - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationPortrait; }
Tja, da hat man grade das bisherige Layout-System in den Griff bekommen, ändert sich mal wieder alles.
Lästige Warnings im Code von anderen
Gerade wer die Regel verfolgt, „Warnings = Errors“, der ärgert sich über unsauberen Code anderer. Aber in der realität kann man nicht jede Codezeile von anderen fixen, bloss weil da ne Warning hochkommt. Daher kann man sich elegant dieser Warnings wie folgt entledigen, z.B. wenn man weiß das der Code so in Ordnung ist. Man schaltet kurzzeitig die Compilerdiagnostik aus (PUSH einer neuen Regel) für die entsprechenden Warnungen und danach wieder ein (POP der hinzugefügten Diagnoseregel).
// NEUE DIAGNOSEREGEL PUSHEN #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-nonliteral" - (void)logMessage:(NSString *)format level:(LoggingLevel)level withParameters:(va_list)valist { if (level >= self.loggingLevel) { NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:valist]; } // HINZUGEFÜGTE DIAGNOSEREGEL ENTFERNEN #pragma clang diagnostic pop
Einfach, oder? Und hilft auch bei anderen Diagnosealarmen die eher zu den false positives gezählt werden dürfen.
Objective-C: Ein DEBUG-flag, das nicht mehr von Xcode bestimmt/gehijacked wird
Xcode setzt von Haus aus gerne bei einem Development Build das DEBUG flag in den PRECOMPILER STATEMENTS auf TRUE, jedenfalls seit einer Weile schon. Ich beziehe bich öfters auf dieses Flag, um bestimmten Code und bestimmte Code-Bestandteile nur dann auszuführen, wenn die App in Entwicklung ist. Doch ab und an hätte ich ja gerne auch mal einen RUN mit DEBUG = FALSE auch wenn ich einen Development Build fahre. Dafür müsste ich jetzt normalerweise in den Einstellungsscreens (diese Excel-Tabellen-mäßige Parameter-Wüste) das DEBUG Zeug deaktivieren. Schneller und einfacher gehts, wenn man ein eigenes DEBUG flag hat, bei dem man weiß, dass da keiner dran rumdreht auch Xcode nicht. Ich meinen precompiler header files (.pch) mache ich daher oft das Folgende:
// SETUP OWN DEBUG FLAG #define DEBUG_MASTER 1 // SETUP DEBUG FLAG DEFINED BY XCODE #ifndef DEBUG #define DEBUG DEBUG_MASTER #else #undef DEBUG #define DEBUG DEBUG_MASTER #endif
Wenn man nämlich einfach das DEBUG von Xcode nochmal definiert hilft das nicht und es gibt eine warning. Daher definiere ich das optional weg und definiere es mit meinem MASTER_DEBUG flagzustand neu. Funktioniert zuverlässig!
How Do I Declare A Block in Objective-C?
The following text was copied from a webpage (see footer/source note) because it is really useful for those damn block statements ‚ya know?
As an instance variable:
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
As a property:
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
As a method parameter:
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName {...}
As an argument to a method call:
[someObject someMethodThatTakesABlock: ^returnType (parameters) {...}];
As a typedef:
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^(parameters) {...}
Objective-C: Override system locale to have custom app locale at any time
I just want to share a trick on how to gain control over the Locale used for your app. The following code snippet is put in the main-method which kicks of your app.
But basically you should call this code snippet in your app and then make the user quit/terminate the app afterwards to restart with the new set default language AND set these parameters here again depending on a flag you may have stored elsewhere. Because actually all those set default values are actually already used at an earlier point in time i.e. for date formatting.
int main(int argc, char *argv[]) { @autoreleasepool { // OVERRIDE LOCALE (BASICALLY DO THIS WHILE APP RUNS AND LET USER RESTART APP) BOOL shouldOverrideLocale = NO; // LET'S TRY TO OVERRIDE IT WITH en_US NSString *languageIdentifier = @"en"; NSString *countryIdentifier = @"US"; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if( shouldOverrideLocale ) { NSLog( @"OVERRIDING SYSTEM LOCALE WITH : %@_%@",languageIdentifier, countryIdentifier ); [defaults setObject:[NSArray arrayWithObject:languageIdentifier] forKey:@"AppleLanguages"]; [defaults setObject:[NSArray arrayWithObjects:languageIdentifier, nil] forKey:@"NSLanguages"]; [defaults setObject:[NSString stringWithFormat:@"%@_%@", languageIdentifier, countryIdentifier] forKey:@"AppleLocale"]; [defaults synchronize]; } else { NSArray *keysToRemove = @[@"AppleLanguages",@"NSLanguages",@"AppleLocale"]; NSLog( @"RESETTING TO USE SYSTEM LOCALE" ); @try { for( NSString *currentKey in keysToRemove ) { if( [defaults objectForKey:currentKey] ) { [defaults removeObjectForKey:currentKey]; } } } @catch (NSException *exception) { // NOTHNG TO CATCH HERE } @finally { [defaults synchronize]; } } NSString *languageCode = [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleLanguageCode]; NSString *countryCode = [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleCountryCode]; NSLog( @"USING SYSTEM LOCALE: %@_%@", languageCode, countryCode ); return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
If you use this code, keep in mind, that strings and processes related to In-App-Purchase are still delivered in the native language of the user.
How to revert pngcrushed aka optimized PNG files in iOS
Xcode does optimized PNG’s when running them through the build system. It makes them non-standard and uneditable by even Photoshop. To restore an image from the assets bundled in your app, you need to revert the optimization process or at least make it a valid PNG again. This is how…
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -revert-iphone-optimizations -q optimized.png reverted.png
How to export all Apple Keychain Certificates as a .pem file (which format does not matter)
If you have an old Mac which does not get supported any more with updates, you end up having a lot of invalid root certificates in your System keychain. Since several applications like e.g. the Safari Browser use these certs to check authenticity of TLS-secured websites, you need valid ones. Simplest way is to export all those certificates from an up-to-date Mac machine and import those on the legacy machine. The security command helps here. With security list-keychains
you get a list of the relevant Keychains. You can access them also vie the GUI tool. The issue with the GUI tool is… it cannot export more than 1 certificate in one action. The GUI sucks a lot! Just use following command…
security export -k /Library/Keychains/System.keychain -t certs -o /Users/jollyjinx/Xserve/CertsFromSystemKeychain.pem
When successfulle exportet the .pem-
File contains ALL certificates. On the target machine just double-click on the pem-File and Keychain will offer you to import all of them. Some will fail for weird reasons beyond my understanding.
Ein Gedanke zu „Code Snippets“