Simon Fortelny

| NSNull

Recently I got an odd error in Swift 1.2 while using closures.
Error screenshot
As you can see in the gist below there is an error; the closure(transformedNoReturn) fails to return a value even though the return type of the closure is U?. Now if the closure is empty(case transformedEmptyClosure below) then we get the useful error Missing return in a closure expected to return ‘Int?’. But if the closure has statements in it but fails to return(case transformedNoReturn) we get the above error ‘filterMap’ with an argument list of type ‘((String) -> Int?)’ even though the error has nothing to do with the argument type.

I’ve filed a radar on this rdar://20962906

UPDATE : This appears to be fixed in Xcode 7.1 beta 2.

Recently I got an odd error in Swift 1.2 while trying to use the type of a class as an argument to a function.


Error screenshot
The error I got Cannot invoke ‘create’ with no arguments seems odd because while String does not conform to the protocol it does have a type. I would have expected something like String does not conform to ProtocolA

I’ve filed a radar on this 20789322

Recently I needed to create a function that took as its parameter a Type that conformed to two protocols and I learned there are two ways to acomplish this using a where clause or protocol composition in the functions generic parameter types.


The where clause method will also work with classes to enforce subclassing

Every once in a while curiosity strikes me and I want to know what the largest file, in lines, in a code base is. I stitched together a few unix commands to sort all your message files by their line count.

find . -type f -name '*.m' -exec wc -l {} + | sort -n

Great overview of using @IBDesignable and @IBInspectable in xcode6 to allow Interface Builder to show accurate previews of your custom views.

Building custom UI element with ibdesignable

Sometimes while writing scripts for use in a target’s Build Phase I need to find out what enviroment variables are set to at build time. The simplest way I’ve found to do this is to create a new Run Script Phase in the targets Build Phase and add this to it

printenv > ~/Desktop/enviromentVars.txt

The next time you build the target it will create a text file in your Desktop directory with all the enviroment vars for that scheme.

Found a great site for gererating .gitignore file for projects. I’ve used it for making .gitignore files for jekyll and ios projects so far.

gitignore.io

git

Whenever I need to add new devices to our iOS adhoc builds I’m never quite sure if the next build includes the new devices. BUt I found a realy easy way to check. Using this Quick Look plugin you can see all the devices included in a mobile provisioning file.

To find the .mobileprovision file for an adhoc signed .ipa

  • Install the Quicklook plug-in
  • In finder Find the .ipa file and unarchive it (right click -> open with -> Archive Utility)
  • Navigate to the Payload directory and right click on application and ‘Show package contents’.
  • Find the ‘embedded.mobileprovision’ and open with Quick Look
  • Check the ‘Provisioned Devices’ section for the new UDID’s
ios

Here are a few more functions useful in creating CGRect’s from a center point and size.

Example usage:

1
view.frame = CGRectWithCenterWidthHeight(parent.center,30,30);

Full set of functions

interface

1
2
CGRect CGRectWithCenterAndSize(CGPoint center, CGSize size);
CGRect CGRectWithCenterWidthHeight(CGPoint center, CGFloat width,CGFloat height);

implementation

1
2
3
4
5
6
7
CGRect CGRectWithCenterAndSize(CGPoint center, CGSize size){
return CGRectMake(center.x - (size.width/2), center.y - (size.height/2), size.width, size.height);
}
CGRect CGRectWithCenterWidthHeight(CGPoint center, CGFloat width,CGFloat height){
return CGRectWithCenterAndSize(center,CGSizeMake(width, height));
}
ios

I feel like I spend alot of time manipulating CGRects. Awhile ago I found a set of C functions that simplify several common operations. Namely they allow you to change one value in a CGRect without forst storing it in a temp variale.

Here is an example settings the view‘s frame to the parent‘s frame with the size.origin set to 34.

1
view.frame = CGRectSetY(parent.frame,34);

Compared to the traditional way of doing this it seems a whole lot more readable and make’s your intention very clear to future readers of the code.

1
2
3
CGRect childRect = parent.frame;
childRect.origin.y = 34;
view.frame = childRect;

Full set of functions

interface

1
2
3
4
5
6
CGRect CGRectSetWidth(CGRect rect, CGFloat width);
CGRect CGRectSetHeight(CGRect rect, CGFloat height);
CGRect CGRectSetSize(CGRect rect, CGSize size);
CGRect CGRectSetX(CGRect rect, CGFloat x);
CGRect CGRectSetY(CGRect rect, CGFloat y);
CGRect CGRectSetOrigin(CGRect rect, CGPoint origin);

implimentation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CGRect CGRectSetWidth(CGRect rect, CGFloat width) {
return CGRectMake(rect.origin.x, rect.origin.y, width, rect.size.height);
}
CGRect CGRectSetHeight(CGRect rect, CGFloat height) {
return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height);
}
CGRect CGRectSetSize(CGRect rect, CGSize size) {
return CGRectMake(rect.origin.x, rect.origin.y, size.width, size.height);
}
CGRect CGRectSetX(CGRect rect, CGFloat x) {
return CGRectMake(x, rect.origin.y, rect.size.width, rect.size.height);
}
CGRect CGRectSetY(CGRect rect, CGFloat y) {
return CGRectMake(rect.origin.x, y, rect.size.width, rect.size.height);
}
CGRect CGRectSetOrigin(CGRect rect, CGPoint origin) {
return CGRectMake(origin.x, origin.y, rect.size.width, rect.size.height);
}
ios