Im trying to create a function to retrieve my Mac's RAM usage but I get alerts saying essentially that my 'scanDouble' and 'scanCharecters(from:into:)' methods have been depreciated and Xcode also throw me these alerts if I compile this code. what are the newer alternatives to these methods?
import Foundation
class RAMUsage {
let processInfo = ProcessInfo.processInfo
func getRAM() {
let physicalMemory = processInfo.physicalMemory
let formatter = ByteCountFormatter()
formatter.countStyle = .memory
let formattedMemoryUsage = formatter.string(fromByteCount: Int64(physicalMemory))
parseAndPrint(formattedMemoryUsage: formattedMemoryUsage)
}
func parseAndPrint(formattedMemoryUsage: String) {
print("Formatted RAM usage: \(formattedMemoryUsage)")
if let gigsOfRAM = parseFormattedRAMUsage(formattedUsage: formattedMemoryUsage) {
print("RAM Usage in Gigabytes: \(gigsOfRAM) GB")
} else {
print("Could not retrieve or parse RAM usage")
}
}
func parseFormattedRAMUsage(formattedUsage: String) -> Double? {
let scanner = Scanner(string: formattedUsage)
var value: Double = 0.0
var unit: NSString?
if scanner.scanDouble(&value) {
scanner.scanCharacters(from: .letters, into: &unit)
if let unitString = unit as String?, unitString.lowercased() == "GB" {
print("Parsed RAM Usage: \(value) GB")
return value
} else {
print("could not parse and return value")
}
}
return nil
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have backend API caller file that retrieves and displays unwrapped JSON data via URLRequest(). All the data is printed to my console when I build the project but it's not being displayed in the actual UI of my iOS simulator.
I have a class in my ContentView that updates the UI and filters the extracted fields shown here below:
class NotionCall: ObservableObject {
@Published var extractedContent: [BlockBody.Block] = []
func makeAPIRequest() {
makeRequest { results in
let extractedData = results.map { block -> BlockBody.Block in
var extractedBlock = block
extractedBlock.ExtractedFields = block.paragraph?.textFields.compactMap { textField in
textField.PlainText ?? textField.RichText ?? textField.content //iterate over PlainText, RichText, and Content fields and return the non nill values
} ?? [] //validate objects even if they are nil
return extractedBlock
}
DispatchQueue.main.async {
self.extractedContent = extractedData
}
}
}
}
@StateObject var NotionCaller = NotionCall() //manage lifecycle of instance
And then below here is my SwiftUI structure that contains List(NotionCaller.extractedContent) { block in ForEach(block.ExtractedFields, id: \.self) { field in Text(field) meant to display the extracted data to the UI:
var body: some View {
NavigationStack {
ZStack {
List(NotionCaller.extractedContent) { block in
ForEach(block.ExtractedFields, id: \.self) { field in
Text(field)
}
}
ZStack {
Color(hex: "#f9f9f9")
.ignoresSafeArea()
VStack {
TextField(" Search keywords", text: $searchKeywords) //change font later
.frame(height: 48)
.overlay(RoundedRectangle(cornerRadius: 30).strokeBorder(style: StrokeStyle()))
.foregroundColor(.white)
.background(.white)
.cornerRadius(30)
.padding()
.scaledToFit()
.frame(maxHeight: .infinity, alignment: .top)
}
VStack {
Spacer()
Divider()
.padding()
HStack {
Button(action: { //add functionality later
}) {
Image("menuButton")
.frame(alignment: .bottom)
.padding(.horizontal, 42)
Spacer()
}
HStack {
Button(action: { //add functionality later
}) {
Image("notificationButton")
.frame(alignment: .leading)
.padding(.leading, 30)
Spacer()
}
}
HStack {
Button(action: {
}) {
Image("notionImportButton")
.frame( alignment: .trailing)
.padding(.horizontal)
.padding(.horizontal)
}
}
}
.onAppear {
NotionCaller.makeAPIRequest()
}
}
}
}
}
}
}
Im getting a scoping error in the default App.swift file of my Xcode project and ive done everything to try to solve the issue, my ContentView struct is at the top level, ive cleaned the build folder a hundred times, restarted Xcode, cleared the derived data folder for nothing to happen. Here is my ContentView.swift file below.
protocol runPyAndSendRequestRunnable {
func runPyServer() -> String
func sendRequest(inputText: String, completion: @escaping(String) -> Void)
}
func runPyServer() -> String {
print("server run")
return "server run"
}
func sendRequest() -> String {
print("request sent")
return "request sent"
}
struct MyPyType: runPyAndSendRequestRunnable {
func runPyServer() -> String {
return "server started"
}
func sendRequest(inputText: String,completion: @escaping(String) ->Void) {
let userInput = inputText
guard let url = URL(string:"http://localhost:8080/MacGPT") else {
completion("Error: failed to obtain url")
return
}
}
struct ContentView: View {
var viewController: runPyAndSendRequestRunnable? = MyPyType()
@State private var text: String = ""
@State private var filePath = ""
@State private var inputText = ""
var body: some View {
makeContent()
.onAppear{
NSApp.mainWindow?.makeFirstResponder(NSApp.mainWindow?.contentView)
}
}
func makeContent() -> some View {
ScrollView {
HStack {
VStack {
VStack(alignment: .center, spacing: 200) {
makeGlobeImage()
makeSecondLogo()
makeTitle()
makeSubtitle()
makeTextFieldAndEnter()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
.frame(maxWidth: .infinity)
}
}
.background(Color.white.opacity(0.9))
.cornerRadius(12)
.padding(.horizontal, 57)
.padding(.bottom, 80)
.frame(minWidth: 1600, minHeight: 1050)
.background(Color.white.opacity(0.1))
.cornerRadius(12)
}
func makeGlobeImage() -> some View {
Image(systemName: "globe")
.foregroundColor(.blue)
.font(.system(size: 40))
.offset(y: 348)
.offset(x: -240)
}
func makeSecondLogo() -> some View {
Image("second Logo")
.resizable()
.scaledToFit()
.frame(width: 90, height: 90)
.offset(x: 185)
.offset(y: 78)
}
func makeTitle() -> some View {
Text("Mac GPT")
.font(Font.custom("Futura", size: 77))
.foregroundColor(Color.black)
.padding(2.15)
.overlay(RoundedRectangle(cornerRadius: 20).stroke(Color.gray, lineWidth: 1.0))
.offset(x: -37)
.offset(y: -221)
}
func makeSubtitle() -> some View {
VStack {
Spacer()
Text("Access the power of AI right from your Mac's homescreen, just for Mac.")
.font(Font.custom("Futura", size: 18.6))
.fontWeight(.bold)
.padding(.vertical, 11)
}
.offset(y: -20)
.offset(x: -40)
}
func makeTextFieldAndEnter() -> some View {
ZStack {
Spacer()
TextField("Ask Mac GPT...", text: $inputText, onCommit: {
executeProcess(withInput: inputText) { response in
print(response)
}
})
.font(Font.custom("Futura", size: 17.4))
.padding(.horizontal, 25)
.padding(.vertical, 15)
.background(Color.white)
.cornerRadius(29)
.overlay(
RoundedRectangle(cornerRadius: 27.9).stroke(Color.gray, lineWidth: 1.0)
)
.offset(y: -200)
.padding(.horizontal, 35)
}
}
func executeProcess(withInput input: String, completion: @escaping (String) -> Void ) {
DispatchQueue.global().async {
DispatchQueue.main.async {
guard !input.isEmpty else {
print("TextField is empty, enter input in the text field")
return
}
self.viewController?.runPyServer() // add closures
self.viewController?.sendRequest(inputText: input) { response in
completion(response)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
}
-code`
Im making an API call using notions API to access and retrieve data from my Notion page and I'm successfully making the url request and accessing the page, however I seem to be struggling with returning the actual data that I have in that page and parsing the JSON data as right now, my console only outputs the makeup of my notion page rather than the formatted and parsed data. I made a codable struct meant to replicate the structure of a notion page based off their documentation then I'm passing that struct to my JSON parsing function but my data still is not being parsed and returned. heres what I have.
import Foundation
struct Page: Codable, Hashable { //Codable struct for notion "Page" for defining content aswell as object representation in a codable struct of all the basic components that make up a notion page per notion's documentation
let created_time: String
let created_by: String
let last_edited_time: String
let object: String
let cover: String
let emoji: String
let icon: String
struct properties: Codable, Hashable {
let title: String
let dueDate: String
let status: String
}
struct dueDate: Codable, Hashable {
let id: String
let type: String
let date: String
let start: String
let end: String? //optionals added to "end" and "time_zone" as these values are set to null in the documentation
let time_zone: String?
}
struct Title: Codable,Hashable {
let id: String
let type: String
let title: [String]
}
struct annotations: Codable, Hashable {
let bold: Bool
let italic: Bool
let strikethrough: Bool
let underline: Bool
let code: Bool
let color: String
}
let English: String
let Korean: String
let Pronounciation: String
let in_trash: Bool
let public_url: String?
let annotations: Bool
}
let url = URL(string: "https://api.notion.com/v1/pages/8efc0ca3d9cc44fbb1f34383b794b817")
let apiKey = "secret_Olc3LXnpDW6gI8o0Eu11lQr2krU4b870ryjFPJGCZs4"
let session = URLSession.shared
func makeRequest() {
if let url = url {
var request = URLRequest(url: url)
let header = "Bearer " + apiKey //authorization header declaration
request.addValue(header, forHTTPHeaderField: "authorization") //append apikey
request.addValue("2022-06-28",forHTTPHeaderField: "Notion-Version") //specify version per notions requirments
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let httpError = error {
print("could not establish HTTP connection:\(httpError)")
} else {
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
} else {
print("invalid api key:\(httpResponse.statusCode)")
}
}
}
if let unwrapData = data { //safely unwrapping the data value using if let
if let makeString = String(data: unwrapData, encoding: .utf8) {
print(makeString)
} else {
print("no data is being returned:")
}
do {
let decoder = JSONDecoder() //JSONDecoder method to decode api data,
let codeUnwrappedData = try decoder.decode(Page.self,from: unwrapData) //Page. specifies its a struct, from: passes the data parmeter that contains the api data to be decoded //PASS STRUCTURESDATABASE STRUCT
print("data:\(codeUnwrappedData)")
} catch {
print("could not parse json data")
}
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print(String(data: unwrapData, encoding: .utf8)!)
} else {
print("unsuccessful http response:\(httpResponse)")
}
}
}
}
task.resume()
}
}
I have a C file for accessing the apple smc and I have the corresponding header file with my declarations in it but when I build my Xcode project I get the error:
"ld: Undefined symbols:
_getTemperature, referenced from:
_main in getsmc.o
clang: error: linker comm"
#include <stdio.h>
#include <IOKit/IOKitLib.h>
typedef struct {
uint32_t datasize;
uint32_t datatype;
uint8_t data[32];
} SMCVal_t;
io_connect_t conn;
kern_return_t openSMC(void) {
kern_return_t result;
kern_return_t service;
io_iterator_t iterator;
service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator);
if(service == 0) {
printf("error: could not match dictionary");
return 0;
}
result = IOServiceOpen(service, mach_task_self(), 0, &conn);
IOObjectRelease(service);
return 0;
}
kern_return_t closeSMC(void) {
return IOServiceClose(conn);
}
double getTemperature(char *key);
kern_return_t readSMC(char *key, SMCVal_t *val) {
kern_return_t result;
uint32_t keyCode = *(uint32_t *)key;
SMCVal_t inputStruct;
SMCVal_t outputStruct;
inputStruct.datasize = sizeof(SMCVal_t);
inputStruct.datatype = 'I' << 24; //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left
inputStruct.data[0] = keyCode;
result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize);
if (result == kIOReturnSuccess) {
if (val -> datasize > 0) {
if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) {
float temp = *(float *)val -> data;
return temp;
}
}
}
return 0.0;
}
int main(void) {
kern_return_t result;
result = openSMC();
if(result == kIOReturnSuccess) {
double temp = getTemperature("TC0P");
printf("temp: %.2f\n", temp);
result = closeSMC();
}
return 0;
}
Im getting a duplicate symbols error when I build my Xcode project and Xcode doesn't specify what or where in my code is there a duplicate:
"1 duplicate symbols" "Showing Recent Issues Linker command failed with exit code 1 (use -v to see invocation)
"
#include <stdio.h>
#include <IOKit/IOKitLib.h>
typedef struct {
uint32_t datasize;
uint32_t datatype;
uint8_t data[32];
} SMCVal_t;
io_connect_t conn;
kern_return_t openSMC(void) {
kern_return_t result;
kern_return_t service;
io_iterator_t iterator;
service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator);
if(service == 0) {
printf("error: could not match dictionary");
return 0;
}
result = IOServiceOpen(service, mach_task_self(), 0, &conn);
IOObjectRelease(service);
return 0;
}
kern_return_t closeSMC(void) {
return IOServiceClose(conn);
}
kern_return_t readSMC(char *key, SMCVal_t *val) {
kern_return_t result;
uint32_t keyCode = *(uint32_t *)key;
SMCVal_t inputStruct;
SMCVal_t outputStruct;
inputStruct.datasize = sizeof(SMCVal_t);
inputStruct.datatype = 'I' << 24; //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left
inputStruct.data[0] = keyCode;
result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize);
if (result == kIOReturnSuccess) {
if (val -> datasize > 0) {
if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) { //bit shifting to from 32bit operation associated with the ASCII charecters 'f', 'l', and 't'
float temp = *(float *)val -> data;
return temp;
}
}
}
return 0.0;
}
double getTemperature(char *key) {
SMCVal_t val;
kern_return_t result;
result = readSMC(key, &val);
if(result == kIOReturnSuccess) {
if (val.datasize > 0) {
printf("val.datasize: %u\n", val.datasize);
if (val.datatype != 0) {
double temperature = (double)val.data[0];
return temperature;
}
}
}
return 0.0;
}
double convertToFahrenheit(double Fahrenheit) {
return (Fahrenheit * (9.0 / 5.0)) + 32.0;
}
int main(void) {
kern_return_t result;
result = openSMC();
if(result == kIOReturnSuccess) {
double temp = getTemperature("TC0P");
double temperatureInFahrenheit = convertToFahrenheit(temp);
printf("temp: %.2f\n", temperatureInFahrenheit);
result = closeSMC();
}
return 0;
}
My Xcode project has a c file, a swift file, and a .h header file with my declarations but when I build my xcdc project I get all these unknown type errors that occur specifically in my .h file.
I also get the error "failed to emit precompiled header" error in my Bridging-header-h file:
Im building a macOS application where the UI is a blurry transparent background that is somewhat see through like what apple uses for the macOS control center and I'm using the NSVisualEffectView from AppKit to do so. My question is, does the Xcode simulator accurately portray translucent UI views? in other words: "what you see is what you get" or will the vibrancy be more pronounced when the app is run on my machine itself.
var material: NSVisualEffectView.Material = .contentBackground //blurry background to cover the whole UI
var blendUI: NSVisualEffectView.BlendingMode = .behindWindow // applying the blurry background to the UI window itself
var allowsVibrancy: Bool = true
func makeNSView(context: Context) -> NSVisualEffectView {
let blurryEffectView = NSVisualEffectView()
blurryEffectView.material = material
blurryEffectView.blendingMode = blendUI
return NSVisualEffectView()
}
func updateNSView(_ nsView: NSVisualEffectView, context: Context) { // _ added, no argument label needed
nsView.material = .contentBackground
nsView.blendingMode = blendUI
}
}
struct ContentView: View {
var body: some View {
ZStack{
EffectView(material: NSVisualEffectView.Material.contentBackground, blendUI: NSVisualEffectView.BlendingMode.behindWindow )
}
}
}
Hello, I have a small lightweight macOS application that includes a medium widget but the widget does not update with new data as often as I'd like. I understand that in apple's WidgetKit documentation they mention that apple controls when the widget updates due to battery life concerns, but I'd like to know if theres any way at all to control when the widget updates or when I think it makes sense to do so if I am not able to control how often it refreshes new data.
https://github.com/Alexx1105/MacStat-v2.1
Hi, I'm having this issue that I have have not been able to figure out as I've gone through a checklist and it seems I have everything in place, but im sending my pushToStartTokenUpdates token to a server and im able to test starting a live activity via CURL where it shows my push token going through and even my test payload but after a while I get this issue in my logs where it fails to find a live activity
Push notifications are set up, im sending my token to APN and im even able to start live activities locally.
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
User Notifications
ActivityKit
0
I am building a simple macOS menu bar app in swift that displays my machine's CPU temperature and I'm just testing out my function to make sure it can retrieve the temp and display it in the Xcode terminal but instead my error handler messages are triggered indicating an issue retrieving my machines CPU temp data
"CPU temp °F could not be retrieved temps couldnot be displayed"
import Cocoa
import IOKit
import IOKit.ps
class CPUTempWithServiceMatching {
static func getCPUTemp() -> Double? {
let dictionaryMatching = IOServiceMatching("AppleSMC")
var service = IOServiceGetMatchingService(kIOMainPortDefault, dictionaryMatching)
var temp = "0.0"
if service != 0 {
let key = "TC0P" //thermal zone zero proxy
if let result = IORegistryEntryCreateCFProperty(service, key as CFString, kCFAllocatorDefault, 0 ) {
temp = (result.takeUnretainedValue() as! NSNumber).doubleValue.description
IOObjectRelease(service)
if let CPUTemp = Double(temp) {
print("CPU Temp: \(CPUTemp) °F")
return(CPUTemp)
}
}
print("CPU temp °F could not be retrieved")
}
return nil
}
}
@main
struct program {
static func main() {
if let cpuTemp = CPUTempWithServiceMatching.getCPUTemp() {
print("cpu temp\(cpuTemp) °F")
} else {
print("temps couldnot be displayed")
}
}
}
I have an Xcode project with an obj-c .c file and a .h file aswell as a .swift file where I am calling functions from those obj-c files with a bridging header but when I build my project I get a duplicate symbols error and Xcode doesn't show where.
here is .h header file:
#define smc_h
#include <stdint.h>
#include <mach/mach.h>
#include <IOKit/IOKitLib.h>
typedef struct {
uint32_t datasize;
uint32_t datatype;
uint8_t data[8];
} SMCVal_t;
io_connect_t conn;
kern_return_t openSMC(void);
kern_return_t closeSMC(void);
kern_return_t readSMC(char *key, SMCVal_t *val);
double convertToFahrenheit(SMCVal_t *val);
#endif /* smc_h */
my .c implementation file:
#include "smc.h"
kern_return_t openSMC(void) {
kern_return_t result;
kern_return_t service;
io_iterator_t iterator;
service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator);
if(service == 0) {
printf("error: could not match dictionary");
return 0;
}
result = IOServiceOpen(service, mach_task_self(), 0, &conn);
IOObjectRelease(service);
return 0;
}
kern_return_t closeSMC(void) {
return IOServiceClose(conn);
}
kern_return_t readSMC(char *key, SMCVal_t *val) {
kern_return_t result;
uint32_t keyCode = *(uint32_t *)key;
SMCVal_t inputStruct;
SMCVal_t outputStruct;
inputStruct.datasize = sizeof(SMCVal_t);
inputStruct.datatype = 'I' << 24; //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left
inputStruct.data[0] = keyCode;
result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize);
if (result == kIOReturnSuccess) {
if (val -> datasize > 0) {
if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) { //bit shifting to from 32bit operation associated with the ASCII charecters'f', 'l', and 't', sets datatype field.
double temp = *(double *)val -> data;
return temp;
}
}
}
return 0.0;
}
double convertToFahrenheit(SMCVal_t *val) {
if(val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) { //checking if val->datatype is equal to the result of the bit-shifting operation.
double temp = *(double *)val -> data;
return (temp * 9.0 / 5.0) + 32.0;
}
return 0.0;
}
And my .swift file where my objc functions are called:
import IOKit
public class CPUTempCaller {
public struct SMCVal_t {
var datasize: UInt32
var datatype: UInt32
var data: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
}
@_silgen_name("openSMC")
func openSMC() -> Int32
@_silgen_name("closeSMC")
func closeSMC() -> Int32
@_silgen_name("readSMC")
func readSMC(key: UnsafePointer<CChar>?,val: UnsafeMutablePointer<SMCVal_t>) -> kern_return_t
@_silgen_name("convertToFahrenheit")
func convertToFahrenheit(val: UnsafePointer<SMCVal_t>) -> Double {
let openSM = openSMC()
guard openSM == 0 else {
print("Failed to open SMC: \(openSM)")
return 0.0;
}
let closeSM = closeSMC()
guard closeSM == 0 else {
print("could not close SMC: \(closeSM)")
return 0.0;
}
func convertAndPrintTempValue(key:UnsafePointer<CChar>?,scale: Character, showTemp: Bool ) -> Double? {
var SMCValue = SMCVal_t(datasize: 0, datatype: 0, data:(0,0,0,0,0,0,0,0)) //initializing SMC value
if let Key = key { //check if nil. If not nil, proceed to code block execution
let key = "TC0P"
let keyCString = (key as NSString).utf8String //passing key as null terminated utf8 string
let readSMCResult = readSMC(key: keyCString, val: &SMCValue) //call readSMC obj-C function, store result in "readSMCResult"
if readSMCResult != KERN_SUCCESS {
print("Failed to read SMC: \(readSMCResult)")
}
}
if showTemp { //return nil if showTemp is false
let convertRawToFahrenheit = convertToFahrenheit(val: &SMCValue)
let scaleToStr = String(scale)
print(String(format: "Temperature: %0.1f °%c", convertRawToFahrenheit, scaleToStr))
return nil
} else {
print("could not convert temperature and format values in Fahrenheit")
return nil
}
}
return 0.0;
}
}
I have an Xcode project that include a .c file and .h header file. I am getting a duplicate symbol error and I cannot pinpoint what part of my code is the issue or maybe if it's a configuration issue in my Xcode settings or not.
Here's my .h header file code with my declarations:
#define smc_h
#include <stdint.h>
#include <mach/mach.h>
#include <IOKit/IOKitLib.h>
typedef struct {
uint32_t datasize;
uint32_t datatype;
uint8_t data[8];
} SMCVal_t;
extern io_connect_t conn;
kern_return_t openSMC(void);
kern_return_t closeSMC(void);
kern_return_t readSMC(char *key, SMCVal_t *val);
double convertToFahrenheit(SMCVal_t *val);
#endif /* smc_h */
And here is my .c implementation:
#include "smc.h"
#include <mach/mach.h>
#include <IOKit/IOKitLib.h>
io_connect_t conn;
kern_return_t openSMC(void) {
kern_return_t result;
kern_return_t service;
io_iterator_t iterator;
service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator);
if(service == 0) {
printf("error: could not match dictionary");
return 0;
}
result = IOServiceOpen(service, mach_task_self(), 0, &conn);
IOObjectRelease(service);
return 0;
}
kern_return_t closeSMC(void) {
return IOServiceClose(conn);
}
kern_return_t readSMC(char *key, SMCVal_t *val) {
kern_return_t result;
uint32_t keyCode = *(uint32_t *)key;
SMCVal_t inputStruct;
SMCVal_t outputStruct;
inputStruct.datasize = sizeof(SMCVal_t);
inputStruct.datatype = 'I' << 24; //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left
inputStruct.data[0] = keyCode;
result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize);
if (result == kIOReturnSuccess) {
if (val -> datasize > 0) {
if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) { //bit shifting to from 32bit operation associated with the ASCII charecters'f', 'l', and 't', sets datatype field.
double temp = *(double *)val -> data;
return temp;
}
}
}
return 0.0;
}
double convertToFahrenheit(SMCVal_t *val) {
if(val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) { //checking if val->datatype is equal to the result of the bit-shifting operation.
double temp = *(double *)val -> data;
return (temp * 9.0 / 5.0) + 32.0;
}
return 0.0;
}
I have a swift file where I am calling objective c functions and providing pointers to certain values where needed but im getting the error "
: Cannot convert value of type 'Swift.UnsafeMutablePointer<MacStat.SMCVal_t>' to expected argument type 'Swift.UnsafeMutablePointer<__ObjC.SMCVal_t>'
"
Here is the relevant code block where I am getting the error:
var convertRawToFahrenheit: Double = 0.0
withUnsafeMutablePointer(to: &SMCValue) { pointer in
convertRawToFahrenheit = convertToFahrenheit(val: pointer)
}
print(String(format: "Temperature: %0.1f °%c", convertRawToFahrenheit ))
return nil
} else {
print("could not convert temperature and format values in Fahrenheit")
return nil
}
return 0.0;
}
I already have a bridging header and the path to that header set up so I know the issue Isn't anything that involves my C functions not getting recognized in swift. I will also provide my full code:
import IOKit
public struct SMCVal_t {
var datasize: UInt32
var datatype: UInt32
var data: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
}
@_silgen_name("openSMC")
func openSMC() -> Int32
@_silgen_name("closeSMC")
func closeSMC() -> Int32
@_silgen_name("readSMC")
func readSMC(key: UnsafePointer<CChar>?,val: UnsafeMutablePointer<SMCVal_t>) -> kern_return_t
func convertAndPrintTempValue(key:UnsafePointer<CChar>?,scale: Character, showTemp: Bool ) -> Double? {
let openSM = openSMC()
guard openSM == 0 else {
print("Failed to open SMC: \(openSM)")
return 0.0;
}
let closeSM = closeSMC()
guard closeSM == 0 else {
print("could not close SMC: \(closeSM)")
return 0.0;
}
var SMCValue = SMCVal_t(datasize: 0, datatype: 0, data:(0,0,0,0,0,0,0,0)) //initializing SMC value
if let key = key { //check if nil. If not nil, proceed to code block execution
let key = "TC0P"
let keyCString = (key as NSString).utf8String //passing key as null terminated utf8 string
let readSMCResult = readSMC(key: keyCString, val: &SMCValue) //call readSMC obj-C function, store result in "readSMCResult"
if readSMCResult != KERN_SUCCESS {
print("Failed to read SMC: \(readSMCResult)")
}
}
if showTemp { //return nil if showTemp is false
var convertRawToFahrenheit: Double = 0.0
withUnsafeMutablePointer(to: &SMCValue) { pointer in
convertRawToFahrenheit = convertToFahrenheit(val: pointer)
}
print(String(format: "Temperature: %0.1f °%c", convertRawToFahrenheit ))
return nil
} else {
print("could not convert temperature and format values in Fahrenheit")
return nil
}
return 0.0;
}
Im honestly a bit lost and looking for general pointers. Here is the general flow of my project. I have an Xcode project where I want to return and convert the temperature values accessed from the apple smc and I found a GitHub repo with all the smc key sensors for the M3Pros/Max chips: https://github.com/exelban/stats/issues/1703 basically, I have all these keys stored in an array in obj-c like so:
NSArray *smcKeys = @[ @"Tp01", @"Tp05", @"Tp09", @"Tp0D", @"Tp0b", @"Tp0f", @"Tp0j", @"Tp0n",@"Tp0h", @"Tp0L", @"Tp0S", @"Tp0V", @"Tp0z", @"Tp0v", @"Tp17", @"Tp1F", @"Tp1J", @"Tp1p", @"Tp1h", @"Tp1R", ];
I am passing all these keys by passing 'smcKeys' in a regular C code file I have here that is meant to open, close and read the data shown here:
#include "smc.h"
#include <mach/mach.h>
#include <IOKit/IOKitLib.h>
#include "smckeys.h"
io_connect_t conn;
kern_return_t openSMC(void) {
kern_return_t result;
kern_return_t service;
io_iterator_t iterator;
service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator);
if(service == 0) {
printf("error: could not match dictionary");
return 0;
}
result = IOServiceOpen(service, mach_task_self(), 0, &conn);
IOObjectRelease(service);
return 0;
}
kern_return_t closeSMC(void) {
return IOServiceClose(conn);
}
kern_return_t readSMC(char *smcKeys, SMCVal_t *val) {
kern_return_t result;
uint32_t keyCode = *(uint32_t *)smcKeys;
SMCVal_t inputStruct;
SMCVal_t outputStruct;
inputStruct.datasize = sizeof(SMCVal_t);
inputStruct.datatype = 'I' << 24; //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left
inputStruct.data[0] = keyCode;
result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize);
if (result == kIOReturnSuccess) {
if (val -> datasize > 0) {
if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) { //bit shifting to from 32bit operation associated with the ASCII charecters'f', 'l', and 't', sets datatype field.
double temp = *(double *)val -> data;
return temp;
}
}
}
return 0.0;
}
Which I am then then calling the functions from this file in a swift file and converting the values to Fahrenheit but no data is being printed in my console:
import IOKit
public class getTemperature {
public struct SMCVal_t {
var datasize: UInt32
var datatype: UInt32
var data: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
}
@_silgen_name("openSMC")
func openSMC() -> kern_return_t
@_silgen_name("closeSMC")
func closeSMC() -> kern_return_t
@_silgen_name("readSMC")
func readSMC(key: UnsafePointer<CChar>?,val: UnsafeMutablePointer<SMCVal_t>) -> kern_return_t
func convertAndPrintTempValue(key:UnsafePointer<CChar>?,scale: Character, showTemp: Bool ) -> kern_return_t {
let openSM = openSMC()
guard openSM == 0 else {
print("Failed to open SMC: \(openSM)")
return kern_return_t()
}
let closeSM = closeSMC()
guard closeSM == 0 else {
print("could not close SMC: \(closeSM)")
return IOServiceClose(conn)
}
func convertAndPrint(val: SMCVal_t) -> Double {
if val.datatype == (UInt32("f".utf8.first!) << 24 | UInt32("l".utf8.first!) << 16 | UInt32("t".utf8.first!) << 8) {
let extractedTemp = Double(val.data.0)
return( extractedTemp * 9.0 / 5.0 + 32.0 )
}
return 0.0
}
let smcValue = SMCVal_t(datasize: 0, datatype: 0, data: (0,0,0,0,0,0,0,0))
let convertedVal = convertAndPrint(val: smcValue)
print("Temperarure:\(convertedVal)F°")
return kern_return_t()
}
}
I know this is a lot but I am honestly looking for any tips to fill in any gaps in my knowledge for anyone who's built a similar application meant to extract any sort of data from Mac hardware.