Unable to use NSFontManager methods in swift - swift

In Xcode 6 Beta 6,
I am unable to use any NSFontManager methods in Swift.
For example:
var fontManager = NSFontManager.sharedFontManager()
fontManager.setAction("changeFont:")
I always get the error: NSFontManager does not have a member named setAction
This occurs for any method (e.g. setDelegate, setTarget)
Thanks for any help.

Try this:
fontManager.action = Selector("changeFont:")
Properties are set using the property syntax in Swift.
In ObjC, properties were declared with (if not using #property):
- (X) myProp { return ... }
- (void) setMyProp(X value) { ... }
In Swift, the property declarations look more like C#:
var myProp : X { get { return ... } set { ... } }
So you can't call the setter explicitly using the same method name as in ObjC (though I have actually no idea what it will be compiled into...).

Related

How to reference static Swift Struct or class variables without using the Type name?

It would be nice to be able to use something similar to "self" as an alias to access the enclosing Struct or Class's static variables. Does swift have an alias to do this?
For example:
struct MyStruct {
static let variable = "Hello"
func accessVariable() {
MyStruct.variable // This works
self.variable // I'd like to be able to do this.
}
}
Or class:
class MyClass {
static let variable = "Hello"
func accessVariable() {
MyClass.variable // This works
self.variable // I'd like to be able to do this.
class.variable // Or this would be nice too!
}
}
There are three ways:
MyStruct.variable
type(of:self).variable
Self.variable
The Self keyword is a relatively recent Swift innovation, and is probably your preferred choice here. The advantage of type(of:) and Self over just saying the name is that they are polymorphic.

How to create function variables with parameter in extensions?

When working with Swift - Extensions
As you know, we can create variables for function. i want to create a variable which can hold reference to a function which has parameters.
i have managed to create variable for a function which didn't have any parameters defined for
My code is as follows :-
extension UIAlertController {
var cancelBlock : ()->Void { return {} }
var nameBlock : (nameArg:String?)->Void { }
}
I am getting the following error with "nameBlock"
Computed property must have accessors specified
How should i specify return value ?
use
var nameBlock : (nameArg:String?)->Void? { return nil }

Set property of a class with obj-C runtime methods in Swift

I have a class whose property value I'd like to set at runtime although there is not a signature to set it.
eg:
public class CBCentralManager : NSObject {
public var state: CBCentralManagerState { get }
...
}
I want to be able to change this class's state at will because I'm creating a stub for unit tests.
stub:
class CBCentralManagerStub: CBCentralManager {
func changeState(newState: CBCentralManagerState) {
let val: NSValue = NSValue(&newState, withObjCType: &(CBCentralManagerState.rawValue))
self.setValue(val, forKey:"state")
}
}
In here, I was hoping to use obj-C runtime method,
setValue:forKey to accomplish this but I get the error:
Error: '&' used with non-inout argument of type 'UnsafePointer'
(aka 'UnsafePointer<()>')
Is there any way to set the value of this class at runtime to manipulate this for testing?

How do I declare that a computed property 'throws' in Swift?

class SomeClass {
var someProperty: Int {
throw Err("SNAFU")
}
}
For code like the above, the swift binary complains 'error is not handled because the enclosing function is not declared 'throws'.
How do I declare that 'someProperty' 'throws' in the above?
class SomeClass {
var someProperty throws: Int {
}
}
and
class SomeClass {
var someProperty: throws Int {
}
}
and
class SomeClass {
var someProperty: Int throws {
}
}
don't seem to work.
This functionality is added for read-only computed properties in Swift 5.5 as part of SE-0310 (included in Xcode 13).
Based on SE-0310, the syntax would be:
class SomeClass {
var someProperty: Int {
get throws {
throw Err("SNAFU")
}
}
}
Here is the previous answer for versions of Swift prior to 5.5:
You cannot throw from a computed property. You must use a function if you want to throw. The Declarations section of the Language Reference part at the end of The Swift Programming Language only lists throws (and rethrows) as a keyword for function and initializer declarations.
While it's not possible (yet) to throw from computed properties in Swift, I found Chris Lattner himself adresses this very same question on one of Apple Developer Forums threads:
We agree that you should be able to mark the getters and setters as "throws" in subscripts and computed properties, but haven't gotten there yet. We are likely to support this at some time, but it isn't clear if it will make it in time for Swift 2.
Let me suggest a workaround: a property can be declared as having type of Result<DesiredPropertyType, Error>. This way it can be accessed like this:
do {
try self.failableProperty.get()
} catch {
...
}
get() is a built-in method of Swift's Result.
UPDATE: this is getting addressed in Swift 5.5 with "effectful read-only properties": https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md.

Optional Binding, Capturing References and Closures [possible bug]

I have been trying to get myself acquainted with Swift, but I recently came across this peculiar problem involving Optional Bindings and capturing references within the context of Closures.
Given the following declarations (code abbreviated for clarity; full code provided at the end):
class Thing
{
func giveNameIfSize() -> String? {
/.../
}
}
typealias IterationBlock = (Thing) -> Bool
class Iterable
{
func iterate(block: IterationBlock) {
/.../
}
}
An Iterable object can store a collection of Things and can iterate through them using a closure. Now say we wanted to find the name of the Thing object that has a size property set up. We could do something like this:
var name: String?
iterable.iterate { (someThing) -> Bool in
/*
Assigning the result of the giveNameIfSize() function to
a variable 'name' declared outside of the closure and
captured by reference
*/
if name = someThing.giveNameIfSize() {
return true
}
return false
}
However, the code above generates the following compiler error:
Cannot assign to immutable value of type 'String?'
Curiously enough, the problem disappears when we use another variable in the optional binding:
iterable.iterate { (someThing) -> Bool in
if var tempResult = someThing.giveNameIfSize() {
name = tempResult
return true
}
return false
} /* COMPILES AND RUNS */
The problem is also resolved if we assign a value to the externally declared variable name outside of the optional binding:
iterable.iterate { (someThing) -> Bool in
name = someThing.giveNameIfSize()
if name != nil {
return true
}
return false
} /* ALSO COMPILES AND RUNS */
Full source code here.
Obs.: Tested this code with Swift 1.2, not 2.0.
====
Is this a bug? Or am I missing something?
The error you're receiving is a little misleading, but the underlying problem here is that you're trying to do something that Swift doesn't support. In Swift, you can't use the result of assignment in a condition.
That being said, both of your proposed alternative methods will work, although I tend to think that the first of the two is a little more Swifty.