Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get String from Any in swift3

Tags:

ios

swift

swift3

Such as I get a dic from fetchData:

(lldb) po dic

▿ 3 elements
  ▿ 0 : 2 elements
    - .0 : "total"
    - .1 : 0.00
  ▿ 1 : 2 elements
    - .0 : "year"
    - .1 : 2016
  ▿ 2 : 2 elements
    - .0 : "month"
    - .1 : 12

(lldb) po dic["year"]
▿ Optional<Any>


(lldb) po dic["year"]!
2016

Is there a function to get String form Any?

The function's usage is like below:

let total = UtilSwift.getStrFromAny(dic["total"] as Any )

In objective-c, I written a method:

+ (NSString*)getStringWithoutNull:(id)value
{
    NSString *strValue = @"";
   if(value != nil){
        strValue = [NSString stringWithFormat:@"%@", value];
    }

    if([strValue isEqualToString:@"null"])
    {
        return @"";
    }

    if ([strValue isEqual:[NSNull null]]) {

        return @"";
    }

    return strValue;
}

Is in swift could write a method like this to get String form Any?


The Any maybe Int, String, "", Double, or other type.


EDIT - 1

After the tried in Playground. :

import UIKit

let dict:[String:Any]  = ["aa": 123, "year":1994, "month":"12"]

let string = String(describing:dict["year"]) ?? ""   // Try to turn result into a String, o

print(string)  // If I print(string!), and there will report error.

The warning:

the test


EDIT 2

I know the edit -2 maybe paint the lily, but if when use the func below, when I deliver a Opitional value to the func, the return String will be Opitinal too, how to avoid that?

This below is my test in Playground, dic["b"] as Any convert the parameter to Opitional:

   let dic:[String:Any] = [  // ["b": 12, "A": "A"]

    "A":"A",
    "b":12
]

func stringFromAny(_ value:Any?) -> String {

    if let nonNil = value, !(nonNil is NSNull) {

        return String(describing: nonNil) // "Optional(12)"
    }
    return ""
}

let str = stringFromAny(dic["b"] as Any)  // "Optional(12)"
like image 720
aircraft Avatar asked Dec 05 '16 02:12

aircraft


People also ask

How do you convert something to a string in Swift?

To convert an Int value to a String value in Swift, use String(). String() accepts integer as argument and returns a String value created using the given integer value.

How do I find a character in a string Swift?

Swift 2 String Search The contains() function has been replaced by the contains() method that can be invoked on the characters property of the new Swift 2 String. The find() function has been replaced with a new method called indexOf() that works on your characters property.

What is string string in Swift?

A string is a series of characters, such as "Swift" , that forms a collection. Strings in Swift are Unicode correct and locale insensitive, and are designed to be efficient. The String type bridges with the Objective-C class NSString and offers interoperability with C functions that works with strings.


2 Answers

Try this one:

func stringFromAny(_ value:Any?) -> String {
    if let nonNil = value, !(nonNil is NSNull) {
        return String(describing: nonNil)
    }
    return ""
}

Update:

If the calling code invokes the above function with an Any? parameter that is explicitly cast to Any (a strange scenario which the Swift 3 compiler allows), then it will consider the final type of the parameter to be a non-optional optional, i.e. an Any value where the type Any represents is Any?. Or, in other terms, the value would be considered to be Optional<Any>.some(value:Any?).

In this case, the if let to unwrap the "some" case returns an optional value as the result in the function implementation. Which means that the final string description will include the "Optional" designation.

Because of the various oddities around the fact that the Swift 3 compiler will happily cast between Any and Any? and consider a value of type Any to be a value of type Any? and vice versa, it's actually pretty complicated to detect if an Any really contains an `Any?' or not, and to unwrap accordingly.

A version of this same function, along with some necessary additional extensions is provided below. This version will recursively flatten an Any value containing any number of nested Any? cases inside to retrieve the innermost non-optional value.

While this is what you seem to be looking for, I am of the opinion that it's a lot of hassle to work around something a programmer should not be doing anyway, namely miscasting a known Any? value to be Any because the compiler has a weird exception for that, even when it is not actually true.

Here's the "developer-proof" version of the code:

protocol OptionalType {
    var unsafelyUnwrapped: Any { get }
    var unsafelyFlattened: Any { get }
}

extension Optional: OptionalType {
    var unsafelyUnwrapped: Any { return self.unsafelyUnwrapped }
    var unsafelyFlattened: Any { return (self.unsafelyUnwrapped as? OptionalType)?.unsafelyFlattened ?? self.unsafelyUnwrapped }
}

func stringFromAny(_ value:Any?) -> String {
    switch value {
    case .some(let wrapped):
        if let notNil =  wrapped as? OptionalType, !(notNil.unsafelyFlattened is NSNull) {
            return String(describing: notNil.unsafelyFlattened)
        } else if !(wrapped is OptionalType) {
            return String(describing: wrapped)
        }
        return ""
    case .none :
        return ""
    }
}
like image 64
Daniel Hall Avatar answered Oct 09 '22 09:10

Daniel Hall


Use ! if the value is an optional

String(describing: nonNil)  // "Optional(12)"
String(describing: nonNil!) // "12"
like image 28
sweet-2 Avatar answered Oct 09 '22 08:10

sweet-2