Bug in string value of Any?


(Paul Stevenson) #1

had an issue with this swift code… it built OK in Fire, but crashed at runtime in Android.

public extension String
{
    public static func thisBuildsButCrashesAtRuntime(_ any: Any?) -> String
    {
        guard let a = any
            else { return "NULL" }
        
        return "\(a)"
    }

    public static func thisWorks(_ any: Any?) -> String
    {
        guard let a = any
            else { return "NULL" }
        
        return "\(any!)"
    }
}

(RemObjects) #2

Thanks, logged as bugs://78433


(Carlo Kok) #3

Do you have a more complete testcase? What do I pass to it?


(Paul Stevenson) #4

Sorry Carl, on vacation… back next week. .will reply then


(marc hoffman) #5

No worries, Carlo’s on vacation too :wink:


(Paul Stevenson) #6

this crashed for us with pretty much any string passed in.

thisBuildsButCrashesAtRuntime(“blah”)

but in context we were using this as a generic way to avoid the optional warning for a string in print…

print(“yada (blah) yada”)
will now (swift3) give you a compiler warning if blah is optional

so I replaced them all with

print(“yada (thisBuildsButCrashesAtRuntime(blah)) yada”)

which compiles OK, and was supposed to either return the non null string, or “NULL”… and print it out…
but which actually crashed on Android when we ran it.

changing to the thisWorks case where we don’t use the guard var, but use the parameter again…
works fine.

I don’t recall if they all crashed… or just the ones where blah was in fact optional

so I would check
var s1: String?
var s2: String? = "xyz"
var s3 = “abc”


(RemObjects) #7

bugs://78433 got closed with status cannotrepro.


(Carlo Kok) #8

Tried this:

import java.util
import android.app
import android.content
import android.os
import android.util
import android.view
import android.widget

public class MainActivity: Activity {

	public override func onCreate(_ savedInstanceState: Bundle!) {
		super.onCreate(savedInstanceState)
        print("yada (thisBuildsButCrashesAtRuntime(blah)) yada")
		ContentView = R.layout.main
	}
}

public extension String
{
    public static func thisBuildsButCrashesAtRuntime(_ any: Any?) -> String
    {
        guard let a = any
            else { return "NULL" }
        
        return "\(a)"
    }

    public static func thisWorks(_ any: Any?) -> String
    {
        guard let a = any
            else { return "NULL" }
        
        return "\(any!)"
    }
}

Which works fine, what am I missing?


(Paul Stevenson) #9

Carlo… this is how I can reproduce it…

public class UtilTests
{
static func thisBuildsButCrashesAtRuntime(_ any: Any?) -> String
{
guard let a = any
else { return “NULL” }

    return "\(a)"
}

public func testForFireAny()
{
    print("\(UtilTests.thisBuildsButCrashesAtRuntime("blah"))")
    let blah = "blah"
    print("\(UtilTests.thisBuildsButCrashesAtRuntime(blah))")
}

}

this works fine in swift… (Xcode)…

but if I build that in Fire and run it on Android…

Error in testForFireAny:
com.remobjects.elements.system.DynamicInvokeException: No overload with these parameters
at com.remobjects.elements.system.DynamicHelpers.Invoke()
at com.remobjects.elements.system.DynamicHelpers.Invoke()
at blah.UtilTests.thisBuildsButCrashesAtRuntime(…)
at blah.UtilTests.testForFireAny(…)


(Paul Stevenson) #10

your post says you tried:

print(“yada (thisBuildsButCrashesAtRuntime(blah)) yada”)

won’t that always work? it’s just a literal string…

I assume you meant this… (but maybe you did do this, but the editor took out the backslash when you posted here?)
but then I don’t see a variable called blah anywhere… so I don’t see how your code could compile if you did…

print(“yada \(thisBuildsButCrashesAtRuntime(blah)) yada”)


(Carlo Kok) #11

ah! I think I know what’s going on here.


(RemObjects) #12

bugs://78433 got reopened.


(RemObjects) #13

bugs://78433 got closed with status fixed.