Cannot find 'strideofValue' in scope - swift

I am getting:
Cannot find 'strideofValue' in scope
For below code:
public static func isDebuggerAttached() -> Bool {
var info = kinfo_proc()
var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
var size = strideofValue(info)
let junk = sysctl(&mib, UInt32(mib.count), &info, &size, nil, 0)
assert(junk == 0, "sysctl failed")
return (info.kp_proc.p_flag & P_TRACED) != 0
}
How can I fix the logic?
I tried stride(ofValue:), but that just causes another strange issue:
Type of expression is ambiguous without more context
(With strange I mean that, it should say something like, function exists but not with ofValue label)

There is no strideofValue function in Swift 5, replace strideofValue(info) with MemoryLayout.stride(ofValue: info).

Related

Unresolved identifier error in swift function with nested if loop

I'm currently teaching myself Swift coming from a background of Python recently and Visual Basic originally. I would describe myself as competent in those codes but a novice in Swift. I'm trying to write a function that will return a set number of digits from either the start or end of a long integer. My chosen method has been to convert the integer to a string and then use the prefix or suffix command.
Whilst I can get the function to work if it has no flow control and uses either prefix or suffix (first lot of code), when I try to write one function that does both I get an unresolved identifier error on the turnStringToInteger variable (second lot of code). I'm pretty sure this is because the variable lives within the if {} but if I declare it outside of the if loop (hashed out) this also errors. I appreciate this will have a really simple answer but how do I use the return correctly with a nested if loop?
This works...
//Function to Trim Integer (Prefix Only)
func integerTrim(integer:Int, trimLength:Int) -> Int {
var strFromInteger = String(integer)
var trimmedString = strFromInteger.prefix(trimLength)
var intFromString = Int(trimmedString) ?? 0
return intFromString
}
//Declare Input
var inputInt = 12345678910
//Call Function
var result = integerTrim(integer: inputInt, trimLength: 4)
//Print Results
print(inputInt)
print(result)
This doesn't...!
//Function to trim integer prefix or suffix
func integerTrim(integer:Int, type:String, trimLength:Int) -> Int {
var typeID = type
//var turnStringToInteger: Int
if typeID == "P" {
var turnIntegerToString = String(integer)
var trimmedString = turnIntegerToString.prefix(trimLength)
var turnStringToIngeger = Int(trimmedString) ?? 0
}
else if typeID == "S" {
var turnIntegerToString = String(integer)
var trimmedString = turnIntegerToString.suffix(trimLength)
var turnStringToIngeger = Int(trimmedString) ?? 0
}
return turnStringToInteger
}
//Declare Input
var inputInt = 53737363856453
//Call Function
var result = integerTrim(integer: inputInt, type: "P", trimLength: 4)
//Print Results
print(inputInt)
print(result)
As I am self taught I appreciate I may also not be using best practices. I really want to learn to do this properly so if I am going about all of this the wrong way to begin with I would be equally happy to hear other approaches. For example I did consider turning the integer to an array and then creating the trimmed integer from positions within this array. Would this be more elegant?
If you want to access the variable outside of the scope where it is assigned, you need to declare it in the outer scope.
If you do that without assigning it an initial value, you get an error: variable 'turnStringToInteger' used before being initialized. That happens because Swift sees a path in which turnStringToInteger never gets assigned a value (imagine what happens if "X" is passed in for type).
So your real issue is the use of String as the type for type. It would be better to use an enum that expresses exactly what you want:
enum TrimType {
case prefix, suffix
}
func integerTrim(integer: Int, type: TrimType, trimLength: Int) -> Int {
let typeID = type
var turnStringToInteger: Int
switch typeID {
case .prefix:
let turnIntegerToString = String(integer)
let trimmedString = turnIntegerToString.prefix(trimLength)
turnStringToInteger = Int(trimmedString) ?? 0
case .suffix:
let turnIntegerToString = String(integer)
let trimmedString = turnIntegerToString.suffix(trimLength)
turnStringToInteger = Int(trimmedString) ?? 0
}
return turnStringToInteger
}
Now there are only 2 possibilities for type and the switch handles both.
You call it like this:
let result = integerTrim(integer: inputInt, type: .prefix, trimLength: 4)
... after a little refactoring:
func integerTrim(integer: Int, type: TrimType, trimLength: Int) -> Int {
let turnIntegerToString = String(integer)
let trimmedString: Substring
switch type {
case .prefix:
trimmedString = turnIntegerToString.prefix(trimLength)
case .suffix:
trimmedString = turnIntegerToString.suffix(trimLength)
}
return Int(trimmedString) ?? 0
}
There's a few ways to do this. The root of the problem is your turnIntegerToString lifetime is within the braces - and the return is outside the braces.
func integerTrim(integer:Int, type:String, trimLength:Int) -> Int {
var typeID = type
var turnStringToInteger: Int = 0
// If you don't want to assign it to zero (your nil coalesce implies we can) - instead use...
// var turnStringToInteger: Int! // However - this can crash since your if statement does not cover all situations
if typeID == "P" {
var turnIntegerToString = String(integer)
var trimmedString = turnIntegerToString.prefix(trimLength)
turnStringToIngeger = Int(trimmedString) ?? 0
}
else if typeID == "S" {
var turnIntegerToString = String(integer)
var trimmedString = turnIntegerToString.suffix(trimLength)
turnStringToIngeger = Int(trimmedString) ?? 0
}
return turnStringToInteger
}

MusicEventIteratorGetEventInfo in Xcode 8 beta 6

Up to Xcode 8 beta 5, I could access the event info in a MusicEventIterator, using something like:
var type: MusicEventType = 0
var stamp: MusicTimeStamp = 0
var data: UnsafePointer<()>? = nil
var size: UInt32 = 0
while(hasCurrentEvent != false) {
MusicEventIteratorGetEventInfo(iterator!, &stamp, &type,
&data, &size)
// do stuff with stamp, type, data...
}
I managed to get some help at the Apple dev site on dealing with "data", but getting data in the first place is also broken. I get a warning about using "UnsafeRawPointer" in the declaration of "data", and an error about not being able to use data as an inout argument in the call to MusicEventIteratorGetEventInfo()...
Though I know they're making things more deterministic and future-proof (i.e., for the compiler), it's incredibly frustrating to have the C-interop stuff changing every few months. My MIDI file parser code has already changed 3 times...
For reference, MusicEventIteratorGetEventInfo has the signature:
func MusicEventIteratorGetEventInfo(_ inIterator: MusicEventIterator,
_ outTimeStamp: UnsafeMutablePointer<MusicTimeStamp>,
_ outEventType: UnsafeMutablePointer<MusicEventType>,
_ outEventData: UnsafeMutablePointer<UnsafePointer<Void>>,
_ outEventDataSize: UnsafeMutablePointer<UInt32>) -> OSStatus
Any help greatly appreciated.
The latest reference of MusicEventIteratorGetEventInfo shows this:
Declaration
func MusicEventIteratorGetEventInfo(_ inIterator: MusicEventIterator,
_ outTimeStamp: UnsafeMutablePointer<MusicTimeStamp>,
_ outEventType: UnsafeMutablePointer<MusicEventType>,
_ outEventData: UnsafeMutablePointer<UnsafeRawPointer?>,
_ outEventDataSize: UnsafeMutablePointer<UInt32>) -> OSStatus
The third parameter outEventData is of type UnsafeMutablePointer<UnsafeRawPointer?>.
Generally, when an API claims UnsafeMutablePointer<T>, you declare a variable of type T, and pass it as an inout argument.
So, this should work:
var type: MusicEventType = 0
var stamp: MusicTimeStamp = 0
var data: UnsafeRawPointer? = nil //<- Declare a variable of type `UnsafeRawPointer?`.
var size: UInt32 = 0
while hasCurrentEvent != false {
MusicEventIteratorGetEventInfo(iterator!, &stamp, &type,
&data, &size) //<- Pass it as an inout argument.
// do stuff with stamp, type, data...
}
In case anyone else has the same problem, this seems to work:
// Somewhere to put the raw midi data
var type: MusicEventType = 0
var stamp: MusicTimeStamp = -1
let data: UnsafeMutablePointer<UnsafeRawPointer?> = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: MemoryLayout<MusicEventType>.size)
var size: UInt32 = 0
var tsChangeStamp: MusicTimeStamp = 0
while(hasCurrentEvent != false) {
MusicEventIteratorGetEventInfo(iterator!, &stamp, &type, data, &size)
// do stuff...
}

Convert a Swift Array of String to a to a C string array pointer

I'm on Swift 3, and I need to interact with an C API, which accepts a NULL-terminated list of strings, for example
const char *cmd[] = {"name1", "value1", NULL};
command(cmd);
In Swift, the API was imported like
func command(_ args: UnsafeMutablePointer<UnsafePointer<Int8>?>!)
After trying hundreds of times using type casting or unsafeAddress(of:) I still cannot get this work. Even though I pass a valid pointer that passed compilation, it crashes at runtime saying invalid memory access (at strlen function). Or maybe it's something about ARC?
let array = ["name1", "value1", nil]
// ???
// args: UnsafeMutablePointer<UnsafePointer<Int8>?>
command(args)
You can proceed similarly as in How to pass an array of Swift strings to a C function taking a char ** parameter. It is a bit different because of the different
const-ness of the argument array, and because there is a terminating
nil (which must not be passed to strdup()).
This is how it should work:
let array: [String?] = ["name1", "name2", nil]
// Create [UnsafePointer<Int8>]:
var cargs = array.map { $0.flatMap { UnsafePointer<Int8>(strdup($0)) } }
// Call C function:
let result = command(&cargs)
// Free the duplicated strings:
for ptr in cargs { free(UnsafeMutablePointer(mutating: ptr)) }
This class provides a pointer that works with char** and automatically deallocates the memory, even though it's a struct (using a little trick with a mapped data with deallocator).
public struct CStringArray {
public let pointer: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>
public let count: Int
private var data: Data
public init(_ array: [String]) {
let count = array.count
// Allocate memory to hold the CStrings and a terminating nil
let pointer = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>.allocate(capacity: count + 1)
pointer.initialize(repeating: nil, count: count + 1) // Implicit terminating nil at the end of the array
// Populate the allocated memory with pointers to CStrings
var e = 0
array.forEach {
pointer[e] = strdup($0)
e += 1
}
// This uses the deallocator available on the data structure as a solution to the fact that structs do not have `deinit`
self.data = Data(bytesNoCopy: pointer, count: MemoryLayout<UnsafeMutablePointer<CChar>>.size * count, deallocator: .custom({_,_ in
for i in 0...count - 1 {
free(pointer[i])
}
pointer.deallocate()
}))
self.pointer = pointer
self.count = array.count
}
public subscript(index: Data.Index) -> UnsafeMutablePointer<CChar>? {
get {
precondition(index >= 0 && index < count, "Index out of range")
return pointer[index]
}
}
public subscript(index: Data.Index) -> String? {
get {
precondition(index >= 0 && index < count, "Index out of range")
if let pointee = pointer[index] {
return String(cString: pointee)
}
return nil
}
}
}

Local and Global variables in Swift

I have a simple piece of code that I guess I'm using local and global variables in it. But, I have a hard time understanding what's going wrong in here. I am setting "var hhhh:Int = 0" at first. Then, inside the if statement, I set "hhhh = appleCount["count"] as! Int". Since appleCount["count"] is not zero and has some value, hhhh gets its' value (I tried that uisng a print statement and hhhh is not zero inside if statement), but, later when I print hhhh with print("(hhhh)") outside if, I again get zero for its' value. Does it have something to do with local and global variables? I'm trying to communicate with Parse in the code by the way.
Thanks a lot for your kind help
import UIKit
import Parse
class NewsPageViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad(
var hhhh:Int = 0
var tttt:Int = 0
var cccc:Int = 1
if cccc == 1 {
var query = PFQuery(className: "Count")
query.getObjectInBackgroundWithId("RhC25gVjZm", block: { (object: PFObject?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let appleCount = object {
appleCount["count"] = appleCount["count"] as! Int + 1
hhhh = appleCount["count"] as! Int
appleCount.saveInBackground()
}
})
}
print(hhhh)
}
}
It does not have to do with local and global variables. It has to do with background threads. The code in brackets {} after the parameter label "block" will run in a background thread at a later time.
Your print(hhhh) is running before the block has had a chance to change hhhh. Move the print statement back inside the block so you can see the variable being set.
osteven response helped me a lot understanding the problem. Thanks a lot man. In addition to osteven's response, I just waned to add that a major part of my problem was coming because I was trying to do some mathematical operations on the objects I was trying to save in Parse. So, I also figured that I could create an array, save my objects inside that array, and then access the key and update the values. Here is a sample code of what I am using right now. It does some mathematical operation on two different objects saved in Parse and updates the label's text on screen. For accessing the two objects in Parse and updating them I'm using an array.
Hope the answers here will help someone in future as the awesome people of StackOverFlow are helping me now.
Peace!
var hhhh : [Int] = []
#IBOutlet weak var jPercent: UILabel!
#IBOutlet weak var yPercent: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
var query = PFQuery(className: "Count")
if cccc == 1 {
query.getObjectInBackgroundWithId("DcU9tdRdnl", block: { (object: PFObject?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let jCount = object {
jCount["count"] = jCount["count"] as! Int + 1
jCount.saveInBackground()
}
})
} else if cccc == 2 {
query.getObjectInBackgroundWithId("5Bq4HJbFa3", block: { (object: PFObject?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let yCount = object {
yCount["count"] = yCount["count"] as! Int + 1
yCount.saveInBackground()
}
})
}
//shouldn't use same query for findObjectsInBackgroundWithBlock and getObjectInBackgroundWithId otherwise you'll get a runtime error
var query2 = PFQuery(className: "Count")
query2.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let users = objects {
for object in users {
if let user = object["count"] as? Int {
self.hhhh.append(user)
}
}
}
var gggg = 100*Float(self.hhhh[0])/(Float(self.hhhh[0]+self.hhhh[1]))
self.yPercent.text = String(format: "%.1f", gggg) + "%"
self.jPercent.text = String(format: "%.1f", 100 - gggg) + "%"
print(self.hhhh[0])
}
}

How to correctly initialize an UnsafePointer in Swift?

I'm trying to use CTFontCreatePathForGlyph(font: CTFont?, glyph: CGGlyph, transform: CConstPointer<CGAffineTransform>):
let myFont = CTFontCreateWithName("Helvetica", 12, nil)
let myGlyph = CTFontGetGlyphWithName(myFont, "a")
let myTransform = CGAffineTransformIdentity
But how do I correctly pass myTransform to CTFontCreatePathForGlyph?
I've tried creating a myTransformPointer to pass to the function like so:
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer().initialize(newvalue: myTransform)
but I get this error:
Playground execution failed: error: <REPL>:20:76: error: '()' is not convertible to 'UnsafePointer<CGAffineTransform>'
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer().initialize(newvalue: myTransform)
so then I tried explicitly naming the type:
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer<CGAffineTransform>().initialize(newvalue: myTransform)
and then I get a different error:
Playground execution failed: error: <REPL>:20:95: error: could not find an overload for 'init' that accepts the supplied arguments
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer<CGAffineTransform>().initialize(newvalue: myTransform)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The auto-complete suggests this should work?
The simplest solution is using withUnsafePointer function:
let myFont = CTFontCreateWithName("Helvetica", 12, nil)
let myGlyph = CTFontGetGlyphWithName(myFont, "a")
var myTransform = CGAffineTransformIdentity
var path = withUnsafePointer(&myTransform) { (pointer: UnsafePointer<CGAffineTransform>) -> (CGPath) in
return CTFontCreatePathForGlyph(myFont, myGlyph, pointer)
}
The initialize is not a constructor. You would have to alloc a new memory using UnsafePointer<T>.alloc, then initialize and then dealloc. Function withUnsafePointer does that all for you.
Note that myTransform cannot be a constant (var not let) otherwise you cannot use it for an inout param (&myTransform).