depreciated methods

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
        
    }
}
Answered by DTS Engineer in 775131022

Those functions do seem to be deprecated in current macOS versions. It's unclear why the documentation is out of date.

The solution is to use the newer versions of these functions such as scanDouble(representation: .decimal). The differ in that they return the scanned value, rather than taking a pointer to memory to store the value. Failure is indicated by a nil result instead of a false return value.

scanDouble is not marked as deprecated in documentation of Xcode 15.0.

Which version of Xcode are you using ?

Accepted Answer

Those functions do seem to be deprecated in current macOS versions. It's unclear why the documentation is out of date.

The solution is to use the newer versions of these functions such as scanDouble(representation: .decimal). The differ in that they return the scanned value, rather than taking a pointer to memory to store the value. Failure is indicated by a nil result instead of a false return value.

The updated version of scanCharacters is:

 public func scanCharacters(from set: CharacterSet) -> String?

https://developer.apple.com/documentation/foundation/scanner/3200281-scancharacters/

Incidentally, to check all this out, I used "Jump to Definition" on scanDouble in Xcode, from the right-click context menu. That took me to a "generated" Swift header that showed all of the relevant function declarations together, and from there I was able to see the deprecations and the new functions.

For example, though it's not directly relevant to your question, I figured out there are no replacements for the older scanHex… functions because they're subsumed by the scan…(representation:) functions where the parameter distinguishes between decimal and hex input.

Can you post an updated code fragment for us to look at?

Taking a step back…

What mechanism are you using to “to retrieve my Mac's RAM usage” that involves parsing strings to get numeric values?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo @Polyphonic UPDATE: here is my updated code that some of you were requesting. I have the updated methods implemented but im getting the error "Cannot convert return expression of type 'Double' to return type 'String?'"

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 let scannedValue = scanner.scanDouble(representation: .decimal) {
            value = scannedValue
            func scanCharacters(from set: CharacterSet) -> String? {
                
                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
            
        }
    }
}

I’m confused by this code snippet. You’re getting a binary value from the physicalMemory property, which makes sense. You then render it to a string and then parse that string. Why are you doing that? Normally folks want one of two things:

  • A binary value, in which can you can use physicalMemory directly

  • A string, in which case you render the binary value to a string using a formatter (like ByteCountFormatter)

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

depreciated methods
 
 
Q