iOS Méthodes non documentées


Exemple

Il existe une variété de méthodes non documentées sur UIColor qui exposent des couleurs ou des fonctionnalités alternatives. Ceux-ci peuvent être trouvés dans le fichier d'en-tête privé UIColor . Je vais documenter l'utilisation de deux méthodes privées, styleString() et _systemDestructiveTintColor() .

styleString

Depuis iOS 2.0, il existe une méthode d'instance privée sur UIColor appelée styleString qui renvoie une représentation de la chaîne RVB ou RGBA, même pour des couleurs comme whiteColor dehors de l'espace RVB.

Objectif c:

@interface UIColor (Private)

- (NSString *)styleString;

@end

// ...

[[UIColor whiteColor] styleString]; // rgb(255,255,255)
[[UIColor redColor] styleString]; // rgb(255,0,0)
[[UIColor lightTextColor] styleString]; // rgba(255,255,255,0.600000)

Dans Swift, vous pouvez utiliser un en-tête de pontage pour exposer l'interface. Avec pure Swift, vous devrez créer un protocole @objc avec la méthode privée et unsafeBitCast UIColor avec le protocole:

@objc protocol  UIColorPrivate {
    func styleString() -> String
}

let white = UIColor.whiteColor()
let red = UIColor.redColor()
let lightTextColor = UIColor.lightTextColor()

let whitePrivate = unsafeBitCast(white, UIColorPrivate.self)
let redPrivate = unsafeBitCast(red, UIColorPrivate.self)
let lightTextColorPrivate = unsafeBitCast(lightTextColor, UIColorPrivate.self)

whitePrivate.styleString() // rgb(255,255,255)
redPrivate.styleString() // rgb(255,0,0)
lightTextColorPrivate.styleString() // rgba(255,255,255,0.600000)

_systemDestructiveTintColor()

Il existe une méthode de classe non documentée sur UIColor appelée _systemDestructiveTintColor qui renvoie la couleur rouge utilisée par les boutons système destructeurs:

let red = UIColor.performSelector("_systemDestructiveTintColor").takeUnretainedValue()

Il retourne un objet non géré, que vous devez appeler .takeUnretainedValue() car la propriété de couleur n'a pas été transférée à notre propre objet.

Comme avec toute API non documentée, vous devez faire attention lorsque vous essayez d'utiliser cette méthode:

if UIColor.respondsToSelector("_systemDestructiveTintColor") {
    if let red = UIColor.performSelector("_systemDestructiveTintColor").takeUnretainedValue() as? UIColor {
        // use the color
    }
}

ou en utilisant un protocole:

@objc protocol UIColorPrivateStatic {
    func _systemDestructiveTintColor() -> UIColor
}

let privateClass = UIColor.self as! UIColorPrivateStatic
privateClass._systemDestructiveTintColor() // UIDeviceRGBColorSpace 1 0.231373 0.188235 1