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
Post
Replies
Boosts
Views
Activity
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 )
}
}
}
I know this is a more abnormal question to ask on this forum but I really would like to gauge feedback from a community of other Swift developers on an idea. A colleague and I are seriously considering building a open-source web based SwiftUI component catalog that feature a collection of prebuilt modular components very similar to Shadcn for those of you who have worked in React but for SwiftUI where you can also contribute your own SwiftUI elements. Im curious if this would be something iOS/Swift devs would be possibly interested in and would love to hear thoughts on this idea. This is not a component library as Xcode technically has one thats built in, but rather fully built out SwiftUI elements such as UIs that use glass morphism for macOS, calendars for iOS apps, charts, etc.
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()
}
}
}
}
}
}
}
I have a bunch of JSOn data printed to my console but I want that data to be displayed in my UI on the iOS simulator and content view UI. ill show the class with my instances and property wrapper im using aswell as the function thats calling my other code that displays the data in the console
@Published var makeapirequest: String = "" //make sure instance is correct
func makeAPIRequest() {
makeRequest()
}
}
@StateObject public var NotionCaller = NotionCall() //manage lifecycle of instance
and then below is the Text() line I added the display the data aswell as the onAppear modifier
NotionCaller.makeAPIRequest()
}
Text(NotionCaller.makeapirequest)
im trying to display the data by calling the instance of the function that calls makeRequest() but the data is still being displayed in the console rather than in my swiftUI.
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()
}
}
Im using Notions API to print out some data from one of my own pages in notion and im using URLSession to make the request then parsing the unwrapped data but nothing is being returned to my console and I know my endpoint and API key is correct. I've gone through the notion API documentation can't can't seem to find anything in it that I am not doing or doing wrong. Ill provide my code as well as the documentation I've been consulting: https://developers.notion.com/reference/intro
import Foundation
struct Page: Codable {
let id: String
let title: String
}
let endpoint = URL(string: "https://api.notion.com/v1/pages/8efc0ca3d9cc44fbb1f34383b794b817")
let apiKey = "… redacted …"
let session = URLSession.shared
func makeRequest() {
if let endpoint = endpoint {
let task = URLSession.shared.dataTask(with: endpoint) { data, response, error in
if let taskError = error {
print("could not establish url request:\(taskError)")
return
}
if let unwrapData = data { //safely unwrapping the data value using if let
do {
let decoder = JSONDecoder() //JSONDecoder method to decode api data,
let codeUnwrappedData = try decoder.decode(Page.self,from: unwrapData) //type: specifies its a struct, from: passes the data parmeter that contains the api data to be decoded
} catch {
print("could not parse json data")
}
}
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
if let apiData = data {
print(String(data: apiData, encoding: .utf8)!)
}
} else {
print("unsuccessful http response:\(httpResponse)")
}
makeRequest()
}
}
task.resume()
}
}
I have an async function where im using the withUnsafeContinuation method and closure but for some reason Xcode is not letting me pass either 'error' or 'Error' for continuation.resume(throwing:). I get the error "Cannot convert value of type 'any Error'"
public func parseResponseData(data: Data) async throws -> TextResult {
return try await withUnsafeContinuation { continuation in
Task {
do {
let decoder = JSONDecoder()
let result = try await decoder.decode(TextResult.self, from: data)
continuation.resume(returning: result)
} catch {
continuation.resume(throwing: error)
}
}
}
}
I have some c code that returns memory usage of a current task on my machine and recently redacted it to use the proc_getallinfio struct so I can instead retrieve systemwide memory usage. im calling that code in swift however im getting the error "Initializer 'init(_:)' requires that 'proc_taskallinfo' conform to 'BinaryInteger'" and im not sure what the appropriate field is to pass that works with proc_getallinfo struct. resident_size does not work in this context.
import IOKit
import Foundation
@_silgen_name("kernMem")
func kernMem(storeMemData: UnsafeMutablePointer <proc_taskallinfo>) -> kern_return_t
@main
struct MacStatAppApp: App {
@State public var printMemory: String = "" //dynamic state object to store data that will be passed to swiftUI
var body: some Scene {
WindowGroup {
ContentView(printMemory: $printMemory) //binding for printMemory to pass data to contentview
.onAppear {
var storeMemData = proc_taskallinfo() //define pointer
let result = kernMem(storeMemData: &storeMemData)
if result == KERN_SUCCESS {
let memoryUsage = Double(storeMemData) / (1024.0 * 1024.0 * 1024.0) //conversion for GB, 1024 to the power of 3
print(String(format: "memory usage: %.2f GB", memoryUsage))
} else {
print("failed to obtain memory usage data:\(result)")
}
}
}
}
}
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.
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;
}
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 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;
}
}
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 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;
}