I am trying to compare two strings. But this is where I do not understand.
First String comes from a URLSession. What I am doing is, convert incoming data of URLSession, to String using,
let phpResponse = String(data: data!, encoding: .utf8);
And Now I need to compare this string with Plain String which is,
let isWhat = "Success";
But when I try to compare them using ==operator, it says strings are not similar. Actually these two variables shows the same content when I print them into Console.
Then I tried to find the types of these two variables using type(of:) operator and both variables were String. I'm not sure what I am missing here. Can someone help me? Why it says that these two Strings are not same?
Related
I am working on importing a file from a legacy C++ codebase. The file itself is technically a JSON but one of the values is obfuscated with an XOR function in the C++ codebase before I receive it and looks something like this.
{"version": 15, "data": "C\u0016Q45\u0010 46QY\\\u0011\n\u0019a\u0003\u0019}\u001apg"}
The value for "data" is technically a UTF8 string.
I know the algorithm used to decode that data into a usable JSON string. However, I am unable to get swift to parse this into a [String : String] apparently due to formatting issues.
Error Domain=NSCocoaErrorDomain Code=3840 "Unable to convert data to string around character 31."
So far I have managed to get the specific data in question by isolating the subdata
let encryptedData = data.subdata(in: dataPrefixLength ..< dataLength - 2)
Even still, I cannot seem to get swift to parse this into a String when I attempt to do so with UTF8 encoding.
String(data: encryptedData, encoding: .utf8)
It's also worth noting that the String description seems alright in the debugger when inspecting the data itself.
I'd really appreciate any advice.
Thanks!
From your example it looks as if the obfuscation generates binary data and the binary data is put into a string. That's not allowed in JSON. Therefore, it's invalid JSON and any parser with a reasonable amount of validation will reject it.
As an example, take the start of the string:
"C\u0016
It starts with the character "C". That's valid.
Then an escaped character with a hexadecimal values follows: 0016. However, U+0016 is not a valid Unicode codepoint. Therefore it's rejected. It's probably supposed to be the binary byte 0x16. But you can't put that into a JSON string.
You have two options:
Fix the source of the data, e.g. by using a Base64 encoding before putting binary data into JSON.
Write your own JSON parser to handle the invalid JSON.
The available documentation for cordova plugins in iOS is pretty poor, and assumes knowledge of Objective C (which I have never learned). It also seems to skip over certain things you're likely to need to know, like what a CDVInvokedUrlCommand is, exactly, and what types of values can be extracted from it.
I see from the header file for the type that it contains a method argumentAtIndex:, which I presume from Swift examples that I've seen interacts with the swift subscript operator, as these suggest command.arguments[number] as a means of getting the argument. However, I've seen no examples at any point that retrieve an argument of any type other than strings (which return either String or NSString ... and to be honest, I'm not really sure what the difference between these types is). So as I understand it, if I get string values, I can extract them like this:
#objc(myStringAction:)
func myStringAction (command: CDVInvokedUrlCommand) {
let firstString = command.arguments[0] as String;
let secondString = command.arguments[1] as String;
...
}
So, assuming I'm implementing another action myComplexAction which receives: an integer, a floating point number, an array of integers, and an object containing string values. How can I extract these into appropriate variables, and what are the resulting types?
After some research, a little bit of learning to read Objective C, and a whole load of digging in the badly-documented Cordova iOS platform library source code, it turns out that the arguments array in the CDVInvokedUrlCommand class is simply a standard array that is initialized from a JSON string using the standard platform NSJSONSerialization service. Therefore, you can assume that the array contains entries of one of the following types:
NSString, NSNumber, or NSNull for standard basic types.
Note that NSNumber is used to encode boolean values as well as numeric ones
NSArray with the same kind of entry types for any arrays
NSDictionary with NSString keys and the same kind of entry types for object values.
Referencing from Swift, the following conversions to standard Swift value types are handled by the runtime:
NSString can be converted to String using as (or implicitly for Swift 2 or earlier)
NSNumber can be converted to an optional of any Swift numeric type using the as? operator (the conversion will fail if the contained number isn't representable in the target type).
NSNull doesn't get converted, but can be tested for using is
NSDictionary is implicitly convertible to [AnyHashable:Any]
NSArray is implicitly converted to [Any].
I have a method that parses a string value and converts it into a selected data type, but I am having difficulty converting strings with nested data structures, eg:
"[1,2,3,{'hello' => 'world'}]"
Currently I convert using the eval method but this causes a massive security issue because the string is actually input by a user.
Is there a different way in which I can parse these types of string? I have tried JSON.parse but it doesn't like the nested hash inside of the array.
I am currently working on Swift script that allows type-checks by compiler for localization strings, something that was sorely needed for a long time. If you are interested, you can check the project on GitHub to get better understanding.
The problem
Part of it is creation of methods from strings, when parser encounters special characters, that are meant to be changed in runtime (%d, %f, %# etc.). String like this:
"PROFILE_INFO" = "I am %#, I am %d years old and %.2fm in height!"
Will get converted to method with following signature:
func profileInfo(value1 : String, value2 : Int, value3 : Float { ...
What I am really curious about and what I could not find anywhere, not even in documentation, is what types are allowed in localization strings. I suspect it goes through default format and there is a lot of types to cover, in which case, I am curious what people used and what types can be omitted. I am using following regexp matching to find the special characters currently, and then converting them to appropriate data types:
let regexp = "%([0-9]*.[0-9]*(d|f|ld)|#|d)"
let matches = self.matchesForRegexInText("%([0-9]*.[0-9]*(d|f|ld)|#|d)", text: string)
I know this covers most of the usual cases, but obviously, I would like to have full coverage if possible.
TLDR:
Q1: What format specifiers are allowed in localization strings - are there any changes from classic string format or everything is the same?
Q2: Is there any better way to convert those characters to appropriate data type than using regexp to parse them out?
Thanks!
I'm using the TBXML framework to parse some XML, but am having problems with the returned string values. The problem is that the returned values contain parts such as "£" instead of £, etc. Is there a convenient way to simply convert all of these into the correct characters so that they can be displayed in a UILabel?
Thanks
Maybe this can help you any further:
HTML character decoding in Objective-C / Cocoa Touch
You maybe can use HTML entities to make your currency character.