[swift-users] Cast CFString to String

Dennis Weissmann dennis at dennisweissmann.me
Tue Dec 5 04:26:54 CST 2017


Thanks Martin, that's much nicer!

- Dennis

> On Dec 5, 2017, at 11:15 AM, Martin R <martinr448 at gmail.com> wrote:
> 
> Another workaround would be
> 
>    public init(uti: String) {
>        switch uti.lowercased() {
>        case String(kUTTypeText):
>            self = .text
>        default:
>            self = .unknown
>        }
>    }
> 
> because there is a `String(_ cocoaString: NSString)` initializer in Foundation.
> 
> Regards, Martin
> 
> 
>> Am 05.12.2017 um 10:09 schrieb Dennis Weissmann via swift-users <swift-users at swift.org>:
>> 
>> Hi swift-users,
>> 
>> I have found another weird behavior (IMO) and wanted to ask for the right way to handle this:
>> 
>> Imagine I want to switch over a Swift string which contains a UTI to map that UTI to an enum.
>> 
>> (A playground is attached for you to easily reproduce, this is tested with Xcode 9.1's included toolchain, also happens in projects)
>> 
>> I would expect the following to work:
>> 
>> import MobileCoreServices
>> 
>> enum MimeType {
>> 
>>    case text
>>    case unknown
>> 
>>    public init(uti: String) {
>>        // Source: https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
>>        switch uti.lowercased() {
>>        case kUTTypeText as String:
>>            self = .text
>>        default:
>>            self = .unknown
>>        }
>>    }
>> 
>> }
>> 
>> The error I get here is
>> 
>> warning: UTITest.playground:8:26: warning: 'as' test is always true
>>        case kUTTypeText as String:
>>                         ^
>> 
>> error: UTITest.playground:8:14: error: expression pattern of type 'CFString' cannot match values of type 'String'
>>        case kUTTypeText as String:
>>             ^~~~~~~~~~~
>>             ^~~~~~~~~~~
>> The only way I found to resolve this is to also import Foundation (which makes sense but is not really obvious).
>> 
>> Alright, that gives me this:
>> 
>> import MobileCoreServices
>> import Foundation
>> 
>> enum MimeType {
>> 
>>    case text
>>    case unknown
>> 
>>    public init(uti: String) {
>>        // Source: https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
>>        switch uti.lowercased() {
>>        case kUTTypeText as String:
>>            self = .text
>>        default:
>>            self = .unknown
>>        }
>>    }
>> 
>> }
>> 
>> warning: UTITest.playground:8:26: warning: 'as' test is always true
>>        case kUTTypeText as String:
>>                         ^
>> 
>> error: UTITest.playground:8:14: error: 'CFString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?
>>        case kUTTypeText as String:
>>             ^
>>                         as String
>> 
>> 
>> Uhm, okay? So let's do that:
>> 
>> enum MimeType {
>> 
>>    case text
>>    case unknown
>> 
>>    public init(uti: String) {
>>        // Source: https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
>>        switch uti.lowercased() {
>>        case kUTTypeText as String as String:
>>            self = .text
>>        default:
>>            self = .unknown
>>        }
>>    }
>> 
>> }
>> 
>> As weird as it looks, it works ... My question is: Is this behavior intended?
>> 
>> Thanks!
>> 
>> - Dennis
>> <UTITest.playground>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
> 



More information about the swift-users mailing list