This is a reference of all the useful links to follow my UIKonf'17 talk on Code Generation in Swift
- Slides on SpeakerDeck
- Keynote Live URL
- All the other files in this GIST contains the code snippets I used in my slides, referenced by slide number.
This is a reference of all the useful links to follow my UIKonf'17 talk on Code Generation in Swift
//outside Block | |
__weak typeof(self) weakSelf = self; | |
//inside Block | |
__strong typeof(self) strongSelf = weakSelf; |
echo "Looking for .orig files to remove" | |
pwd=$(pwd) | |
find . -type f -name \*.orig -exec rm {} \; | |
echo "Done removing .orig files" |
// Add a button to Collapse or Expand files in a Github PR | |
// | |
// See it in action: http://cl.ly/image/1r3q3d0d3b0p | |
// | |
// Install Tampermonkey and add this as a script | |
// ==UserScript== | |
// @name Github PRs: Collapse/expand file | |
// @namespace https://gist.github.com/micho/855b272d2f408f04729e | |
// @version 0.1 |
#!/bin/bash | |
all_assets=`find $1 -type f | uniq | grep -v @2x` | |
for asset in $all_assets; do | |
name=`basename $asset | cut -d . -f 1` | |
count=`git grep $name | grep -v project.pbxproj: | wc -l` | |
echo -e "$count\t$asset" | |
done |
Storyboard Segues initially seem like a pretty cool way to construct interfaces using minimal glue code. But actually, nibs already supported this concept in a much more flexible way.
Certainly, a Storyboard lets you bind a button action up to display a view controller with no code, but in practice you will usually want to pass some data to the new controller, depending on which button you used to get there, and this means implementing the -prepareForSegue:sender: method, which rapidly becomes a giant if/elseif statement of doom, negating most of the benefit of the codeless segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"modalSegue"])
{
ModalViewController *controller = (ModalViewController *)segue.destination;
controller.someProperty = someValue;
INSERT INTO 'snippets' | |
select 487 as 'sid', ':musical_note:' as 'title', '🎵' as 'body', 'None' as 'syntax', 0 as 'usageCount' | |
union select 488, ':musical_score:', '🎼', 'None', 0 | |
union select 489, ':mute:', '🔇', 'None', 0 | |
union select 490, ':nail_care:', '💅', 'None', 0 | |
union select 491, ':name_badge:', '📛', 'None', 0 | |
union select 492, ':necktie:', '👔', 'None', 0 | |
union select 493, ':negative_squared_cross_mark:', '❎', 'None', 0 | |
union select 494, ':neutral_face:', '😐', 'None', 0 | |
union select 495, ':new:', '🆕', 'None', 0 |
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person | |
{ | |
//get email and dismiss picker | |
ABMutableMultiValueRef email = ABRecordCopyValue( person, kABPersonEmailProperty ); | |
CFStringRef emailRef = ABMultiValueCopyValueAtIndex(email, 0); | |
[self dismissModalViewControllerAnimated:YES]; | |
//return NO to not show the contact details | |
return NO; |
// Request authorization to Address Book | |
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init]; | |
picker.peoplePickerDelegate = self; | |
[self presentModalViewController:picker animated:YES]; |