Translate Just 4 Lines of Code from Objective C to Swift (Pointers)

Translate just 4 lines of code from objective c to swift (Pointers)

Presumably the first line is a placeholder for an actual array? If you're actually working with a NULL array pointer, the rest of your code does nothing.

Assuming you're starting from a real CFArrayRef, you can take advantage of bridging: CoreFoundation types are automatically treated like Swift objects, so you don't need to work with CFArrayRef and CFDictionaryRef pointers. The same goes for any other C API that uses the CF type system, so it should also apply to SecIdentity.

There seems to be some weirdness with automatic bridging of CF collections — you can implicitly bridge a CFArray to an NSArray and an NSArray to a Swift Array<T>, you can't just subscript a CFArray.

So your conversion looks something like this (wrapped in a function that handles your assumed array):

func getIdentity(keychainArray: NSArray) -> SecIdentity? {
let dict = keychainArray[0] as Dictionary<String,AnyObject>
let key = kSecImportItemIdentity.takeRetainedValue()
return dict[key] as SecIdentity?
}

If you have a CFArray you can pass it to this function and it'll automatically bridge/cast to NSArray, which then automatically casts to a Swift array for subscripting. Treat item 0 as a Swift dictionary, and you can subscript the dictionary to get the identity out. For the key, you'll need to pull it out of an Unmanaged<CFString> because the Security framework isn't set up for implicit bridging of that constant's declaration.

I've left this function returning an optional, since I don't know wether the array+dictionary you're passing in actually contains an identity. If you're sure it does, you could take out the two question marks.

(This compiles in playground, but I don't have an array containing a dictionary containing an identity handy for testing with, so caveat emptor.)

Objective-C pointer and swift

What you are dealing with (void *info) is a C pointer-to-void, which arrives into Swift as a form of UnsafeRawPointer. This means that type info has been cast away and that memory is being managed elsewhere.

In order to work with this thing as what you believe it to be, i.e. a RunLoopSource, you need to characterize it explicitly as a RunLoopSource. In C, you would cast, as in the example code you posted: (RunLoopSource*)info. In Swift, you rebind.

Observe that in your case this whole thing has been made just a little more complicated by the fact that this UnsafeMutableRawPointer has been wrapped in an Optional, and will have to be unwrapped before you can do anything at all.

Assuming, then, in your case, that info is really an UnsafeMutableRawPointer? bound to a RunLoopSource, you can say:

let rlsptr = info!.assumingMemoryBound(to: RunLoopSource.self)
let rls = rlsptr.pointee

Now rls is a RunLoopSource and you can work with it however you like. Keep in mind, however, that the memory is unmanaged, so you should work with it only here and now.

EDIT By the way, Apple has a really nice document on this entire matter: https://swift.org/migration-guide/se-0107-migrate.html

objective c to swift conversion. (#define and weak)

WeakRef simply gives you a weak reference to some object, and in Swift, that's just weak var foo = obj; it doesn't need a utility method.

WeakReturn can't be replicated in Swift, because the Obj-C macro is used to insert a conditional return in a function. There are no macros in Swift, and the Swift WeakReturn function that you defined does absolutely nothing--it returns whether the object is nil or not; all you've done is make one of those returns explicit. My guess is that this macro was added to the Obj-C code to save some lazy programmer from writing if obj == nil return;.

Swift Pass array by reference to ObjectiveC method

Okay so my guess is that when you are passing nil, you are NOT passing a pointer, since its not pointing to anything, thus your value after that, does not changed.

If you want to pass nil, you may have to change the function to return a pointer to new NSMutableArray, and assign back to the array in your swift code

Create array first in Swift and pass to Obj-c ensure the object has been created and passing proper pointer

How do I use CFArrayRef in Swift?

As explained in
Working with Core Foundation Types, there are two possible solutions when
you return a Core Foundation object from your own function that is imported in Swift:

  • Annotate the function with CF_RETURNS_RETAINED or CF_RETURNS_NOT_RETAINED.
    In your case:

    - (CFArrayRef)someMethod:(someType)someParameter CF_RETURNS_NOT_RETAINED;
  • Or convert the unmanaged object to a memory managed object with takeUnretainedValue() or takeRetainedValue() in Swift. In your case:

    var cfArr = myInstance.someMethod(someValue).takeUnretainedValue()

Converting obj-c code to swift 2 block issue

You need to use the withUnsafeMutablePointer function as documented here. Something along the lines of:

var pixel: JGPixel = // whatever
withUnsafeMutablePointer(&pixel, { (ptr: UnsafeMutablePointer<JGPixel>) -> Void in
pixelData.processPixelsWithBlock({(ptr, x: Int, y: Int) -> Void in

})
})

EDIT: Just realised I forgot to pass ptr to the function properly. Fixed above.

Failed to use CGPoint, the struct, in Swift

The line

CGPoint lineOrigins[numberOfLines];

Creates a C array of CGPoint objects.

It's written inside a function, so it creates a local (stack) variable.
That code will only compile if numberOfLines is a compile-time constant, because the compiler has to allocate a fixed amount of space for your array on the stack at compile time.

C structs are simple "templates" that interpret a block of memory as containing one or more scalar values. The values are stored sequentially in memory.

A C array is also a way of looking at a block of memory, as a sequential series of one or more scalar "things." Those scalar things can be simple scalars like integers, or they can be structs.

When you define a C array like in your example, the compiler makes memory space for the full array, and sets the variable to a pointer to the first element.

The type of lineOrigins is actually type "pointer to CGPoint". In C, an array type and a pointer to an object of that type are interchangeable. It is a bit like a Swift unsafe buffer pointer. There's no range checking.

EDIT:

A similar Swift declaration would be:

var lineOrigins = [CGPoint]()

or, to pre-fill it with a bunch of zero points:

var lineOrigins = [CGPoint](count: numberOfLines, repeatedValue: CGPointZero)

Are pointers to Objective-C arrays (via a bridging header) allowed?

Are you allowed to pass in data from an objective-c code to a glBuffer?

Why wouldn't you be allowed? Swift has a pointer API (UnsafePointer<T>, UnsafeMutablePointer<T>, etc.) exactly for this purpose. Obviously this is "unsafe" in the sense that the underlying memory the [Objective-]C pointer points to could change at anytime without the Swift pointer knowing. It also has no information about the size of the memory block that it points to.

Any C pointers or arrays can be bridged to Swift (probably as UnsafeMutablePointer<Void> which you will need to cast to your OpenGL type).

You can avoid any risk of referencing invalid memory by dereferencing the pointer (if it is non-nil) and copying the value stored at the pointer to a variable in your Swift application.



Related Topics



Leave a reply



Submit