
Al núcleo de la manzana, sirve como una casa para probar los límites de lo que se puede hacer en iOS nativos sin un jailbreak.
Este proyecto es para fines educativos y el código no debe usarse en ninguna aplicación dirigida a la App Store.
Todos los proyectos y fragmentos están hechos y se ejecutan en dispositivos que no son de Jailbreak . Si bien no se probó, la mayoría de los siguientes fragmentos deberían poder correr en parques infantiles en iPad.
import Darwin
import Foundation
/**
Obtains an array of dictionaries representing device battery info. Returns nil if there was an issue retrieving info from battery API.
*/
func deviceBatteryInfo ( ) -> [ [ String : AnyObject ] ] ? {
guard case let handle = dlopen ( " /System/Library/PrivateFrameworks/BatteryCenter.framework/BatteryCenter " , RTLD_LAZY ) , handle != nil ,
let c = NSClassFromString ( " BCBatteryDeviceController " ) as AnyObject as? NSObjectProtocol else {
return nil
}
func sharedInstance ( ) -> String { return " sharedInstance " } // Silence compiler warnings
guard c . responds ( to : Selector ( sharedInstance ( ) ) ) == true else { return nil }
let instance = c . perform ( Selector ( sharedInstance ( ) ) ) . takeUnretainedValue ( )
guard let batteries = instance . value ( forKey : " connectedDevices " ) as? [ AnyObject ] else { return nil }
let batteryInfo = batteries . compactMap { battery -> [ String : AnyObject ] ? in
var propertyCount : UInt32 = 0
guard let properties = class_copyPropertyList ( battery . classForCoder , & propertyCount ) else { return nil }
var batteryDictionary = [ String : AnyObject ] ( )
for i in 0 ..< propertyCount {
let cPropertyName = property_getName ( properties [ Int ( i ) ] )
let pName = String ( cString : cPropertyName )
batteryDictionary [ pName ] = battery . value ( forKey : pName ) as AnyObject
}
free ( properties ) //release Obj-C property structs
return batteryDictionary
}
return batteryInfo
}
print ( " Batteries' Info: ( deviceBatteryInfo ( ) ) " ) ![]()
He creado un proyecto completo en torno a esta idea llamada AppExplorer. Consulte el repositorio para obtener más información y cómo puede implementarlo en su propio proyecto.
class AirplaneManager {
/**
Whether or not airplane mode is enabled. Returns nil if an error occured getting info from API.
*/
static func isAirplaneModeEnabled ( ) -> Bool ? {
guard case let handle = dlopen ( " /System/Library/PrivateFrameworks/AppSupport.framework/AppSupport " , RTLD_LAZY ) , handle != nil ,
let c = NSClassFromString ( " RadiosPreferences " ) as? NSObject . Type else {
return nil
}
let radioPreferences = c . init ( )
if radioPreferences . responds ( to : NSSelectorFromString ( " airplaneMode " ) ) {
return ( radioPreferences . value ( forKey : " airplaneMode " ) as AnyObject ) . boolValue
}
return false
}
}
print ( " Airplane Mode Enabled: ( AirplaneManager . isAirplaneModeEnabled ( ) ) " ) Para utilizar las funciones de SCDYNAMICSTOREATE y SCDYNAMICSTORECOPYVALUE, deberán cambiar las macro __OSX_AVAILABLE_STARTING para estas funciones.
La forma más fácil de hacer esto es ⌘ + ⌥ + CLICK en los nombres de funciones en Xcode que lo llevarán a los encabezados respectivos. Comenta las macros como se ve aquí:
SCDynamicStoreRef __nullable SCDynamicStoreCreate (
CFAllocatorRef __nullable allocator,
CFStringRef name,
SCDynamicStoreCallBack __nullable callout,
SCDynamicStoreContext * __nullable context
) /* __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA) */ ; CFPropertyListRef __nullable SCDynamicStoreCopyValue (
SCDynamicStoreRef __nullable store,
CFStringRef key
) /* __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA) */ ;
let reader = MobileHotspotReader . sharedReader
print ( " Connected Devices: ( reader . numberOfConnectedDevices ) " )
print ( " Connected over Bluetooth: ( reader . connectionsOverBluetooth ) " ) Este código no requiere API privadas, pero utiliza cadenas codificadas que pueden cambiar en futuras versiones del sistema operativo.
print ( " Wifi is Enabled : ( NetworkManager . wifiEnabled ( ) ) " )
print ( " Wifi is Connected : ( NetworkManager . wifiConnected ( ) ) " )
print ( " Currently Tethering : ( NetworkManager . isTethering ( ) ) " ) import Darwin
import UIKit
struct WallpaperLocation : OptionSet {
let rawValue : Int
static let lockscreen = WallpaperLocation ( rawValue : 1 << 0 )
static let homescreen = WallpaperLocation ( rawValue : 1 << 1 )
}
func setWallpaper ( image : UIImage , location : WallpaperLocation ) -> Bool {
guard case let handle = dlopen ( " /System/Library/PrivateFrameworks/SpringBoardUI.framework/SpringBoardUI " , RTLD_LAZY ) , handle != nil else {
return false
}
guard case let symbol = dlsym ( handle , " SBSUIWallpaperSetImageAsWallpaperForLocations " ) , symbol != nil else {
return false
}
typealias methodSignature = @ convention ( c ) ( AnyObject , NSInteger ) -> ( )
let _ = unsafeBitCast ( symbol , to : methodSignature . self ) ( image , location . rawValue )
dlclose ( handle )
return true
}
setWallpaper ( image , location : [ . homescreen , . lockscreen ] )