How to convert a swift String to CFString

2019-02-07 17:16发布

问题:

How can i create a CFString from a native swift String or NSString in swift

    let path:String = NSBundle.mainBundle().pathForResource(name.stringByDeletingPathExtension, ofType:"pdf")
    let string:CFString = ??? path
    let url:CFURLRef = CFURLCreateWithFileSystemPath(allocator:kCFAllocatorDefault, filePath:string, pathStyle:CFURLPathStyle.CFURLPOSIXPathStyle, isDirectory:false)

回答1:

Just cast it:

var str = "Hello, playground" as CFString
NSString(format: "type id: %d", CFGetTypeID(str))


回答2:

If you want to convert a non-literal string, you have to cast it to NSString.

let replacement = "World"
let string = "Hello, \(replacement)"

let cfstring:CFString = string as NSString

Swift knows how to convert a swift string to an NSString and an NSString to a CFString, but seems not to know how to do both steps in one.



回答3:

You cast it between CFString and NSString, or between NSString and String. The trick is that you must double cast when going between CFString and String.

This works:

var cfstr: CFString = "Why does Swift require double casting!?"
var nsstr: NSString = cfstr as NSString
var str: String = nsstr as String

This gives the error "'CFString' is not a subtype of 'NSString'":

var cfstr: CFString = "Why does Swift require double casting!?"
var str: String = cfstr as String


回答4:

Today I was trying to do this in a playground for testing a C API and just import Foundation made "string" as CFString work.



回答5:

If you're trying to convert a variable that contains a Swift string to a CFString I think @freytag nailed it with his explanation.

In case anyone wanted to see an example I thought I'd include a code snippet where I cast a Swift string ("ArialMT" in this case) to an NSString in order to use it with the CTFontCreateWithName function from Core Text (which requires a CFString). (Note: the cast from NSString to CFString is implicit).

    // Create Core Text font with desired size
    let coreTextFont:CTFontRef = CTFontCreateWithName("ArialMT" as NSString, 25.0, nil) 

    // Center text horizontally
    var paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = NSTextAlignment.Center

    // Center text vertically
    let fontBoundingBox: CGRect = CTFontGetBoundingBox(coreTextFont)
    let frameMidpoint = CGRectGetHeight(self.frame) / 2
    let textBoundingBoxMidpoint = CGRectGetHeight(fontBoundingBox) / 2
    let verticalOffsetToCenterTextVertically = frameMidpoint - textBoundingBoxMidpoint

    // Create text with the following attributes
    let attributes = [
        NSFontAttributeName : coreTextFont,
        NSParagraphStyleAttributeName: paragraphStyle,
        kCTForegroundColorAttributeName:UIColor.whiteColor().CGColor
    ]
    var attributedString = NSMutableAttributedString(string:"TextIWantToDisplay", attributes:attributes)

    // Draw text (CTFramesetterCreateFrame requires a path).
    let textPath: CGMutablePathRef = CGPathCreateMutable()
    CGPathAddRect(textPath, nil, CGRectMake(0, verticalOffsetToCenterTextVertically, CGRectGetWidth(self.frame), CGRectGetHeight(fontBoundingBox)))
    let framesetter: CTFramesetterRef = CTFramesetterCreateWithAttributedString(attributedString)
    let frame: CTFrameRef = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributedString.length), textPath, nil)
    CTFrameDraw(frame, context)