addAttribute fails in Swift 1.2 (Xcode 6.3) - xcode

This was working before upgrading to Swift 1.2 and Xcode 6.3.
var mutString : NSMutableAttributedString = NSMutableAttributedString(string: "K2")
mutString.addAttribute(kCTSuperscriptAttributeName, value:-1, range:NSMakeRange(1, 1))
var result : String = mutString.string
The result should contain the string K2 (with "2" as a subscript).
But now I get this error:
Cannot invoke addAttribute with an argument list of type '(CFString!, value:Int, range:NSRange)'
Please point me to the right solution/documentation.

Just add "as! String" after the kCTSuperscriptAttributeName

addAttribute accepts an argument list of type (String, value: AnyObject, range: NSRange). The latter two seem to be fine, but you can't use a CFString! with this method.
You have to use the native Swift String type in Swift 1.2 (which marks a further departure from its Objective-C heritage). Changing kCTSuperscriptAttributeName's type to String should solve the issue.

Related

Eureka forms gives error EXC_BAD_INSTRUCTION INVOP

I have just started using Eureka Forms in my Swift 3 project.
I have created my first form with a TextRow that looks like this:
<<< TextRow() {
$0.tag = tagname
$0.title = title
$0.placeholder = placeholder
}
It displays correctly on the simulator, however when I click in the field I immediately get a crash:
EXC_BAD_INSTRUCTION (code =EXC_1386,INVOP,subcode=0x0)
On the guard line (from the Eureka framework):
private func displayValue(useFormatter: Bool) -> String? {
guard let v = row.value else { return nil }
It must be something simple, can anybody point me in the right direction please?
That error seems to say that the row.value is needed, so maybe you can add an initial value ("") in the init callback. It may be an old or unreleased commit. Please try the latest version or see if the version you used has that particular bug.

swiftyjson cannot convert rawstring back to a json object

I have a json object like thies {"test" : "test"}, but if I convert it to a SwfiftyJSON.JSON object, and then I fetch the rawstring by function rawString(), then I convert the rawstring to a json object, but unfortunately, I can not get the correct json object, if I try to get "test" property or any other property, it always return nil, what is wrong?
SWIFT 5
If you want to get rid of white-spaces and new lines characters from your output, you should disable pretty Printing.
You can achieve this by
let myString = yourJsonObject.rawString(String.Encoding.utf8, options: JSONSerialization.WritingOptions.init(rawValue: 0))
Old versions
let myString = yourJsonObject.rawString(NSUTF8StringEncoding, options: NSJSONWritingOptions(rawValue: 0))
To update Tom's answer;
Swift 4 update:
let myString = yourJsonObject.rawString(String.Encoding.utf8, options: JSONSerialization.WritingOptions.init(rawValue: 0))!
Swift 3 update:
let myString = yourJsonObject.rawString(NSUTF8StringEncoding, options: [.jsonSerialization: JSONSerialization.WritingOptions(rawValue: 0)])

NSLocalizedString should be used directly for exporting XLIFF?

I used to use NSLocalizedString by custom function.
For example, to access Profile.strings, I define this function:
func LocalizedProfile(key: String, comment: String?) {
NSLocalizedString(key, tableName: "Profile", comment: comment ?? "")
}
And, called like this:
let localized = LocalizedProfile("Submit", comment: "For registration")
This method works fine except for exporting XLIFF.
On the Xcode 6.3.2, executting Export for localizationthrows error:
To get error information, I executed via command line:
xcodebuild -exportLocalizations -localizationPath ./xliff -project MyApp.xcodeproj -exportLanguage ja
And, I got this error:
Bad entry in file /Users/mono/Documents/Git/MyApp/Localization.swift (line = 29): Argument is not a literal string.
Defining custom localization method is very useful for me, but I also want to use exporting XLIFF feature.
Are there any methods to resolve this demands?
Export For Localization and xcodebuild -exportLocalizations both generate strings files by looking for invocations of NSLocalizedString(_:tableName:bundle:value:comment:) in code and uses the static values passed into the parameters to create the appropriate strings files.
This means that the only values you can pass into key, comment, value, and tableName are string literals.
Since you're using a wrapper function around NSLocalizedString(_:comment:) to localize your strings, the only time Xcode sees you calling NSLocalizedString(_:comment:) is in that one wrapper function with non-string-literal values, which is invalid.
What you really want to do instead is call NSLocalizedString(_:tableName:comment:) directly.
Alternatively, you can call Bundle.localizedString(forKey:value:table:) in your wrapper function, but then you have to manually create your own strings files for those key-value pairs.
/// - parameter comment: This value is ignored, but should be provided for
/// context at the call site about the requested localized string.
func LocalizedProfile(key: String, comment: String?) -> String {
return Bundle.main.localizedString(forKey: key, value: nil, table: "Profile")
}

String indices in Swift 2

I decided to learn Swift and I decided to start with Swift 2 right away.
So here is a very basic example that's similar to one of the examples from Apple's own e-book about Swift
let greeting = "Guten Tag"
for index in indices(greeting) {
print(greeting[index])
}
I tried this in the playground of Xcode 7 and I received the following error
Cannot invoke 'indices' with an argument list of type '(String)'
I also tried the same thing with Xcode 6 (which is Swift 1.2 AFAIK) and it worked as expected.
Now, my question is: Is this
An error in Xcode 7, it's still a beta release after all, or
Something that just doesn't work anymore with Swift 2 and the e-book just isn't fully updated yet?
Also: If the answer is "2", how would you replace indices(String) in Swift 2?
In a Playground, if you go to menu View > Debug Area > Show debug area, you can see the full error in the console:
/var/folders/2q/1tmskxd92m94__097w5kgxbr0000gn/T/./lldb/94138/playground29.swift:5:14: error: 'indices' is unavailable: access the 'indices' property on the collection
for index in indices(greeting)
Also, Strings do not conform to SequenceTypes anymore, but you can access their elements by calling characters.
So the solution for Swift 2 is to do it like this:
let greeting = "Guten Tag"
for index in greeting.characters.indices {
print(greeting[index])
}
Result:
G
u
t
e
n
T
a
g
Of course, I assume your example is just to test indices, but otherwise you could just do:
for letter in greeting.characters {
print(letter)
}
Just for completion, I have found a very simple way to get characters and substrings out of strings (this is not my code, but I can't remember where I got it from):
include this String extension in your project:
extension String {
subscript (i: Int) -> Character {
return self[self.startIndex.advancedBy(i)]
}
subscript (i: Int) -> String {
return String(self[i] as Character)
}
subscript (r: Range<Int>) -> String {
return substringWithRange(Range(start: startIndex.advancedBy(r.startIndex), end: startIndex.advancedBy(r.endIndex)))
}
}
this will enable you to do:
print("myTest"[3]) //the result is "e"
print("myTest"[1...3]) //the result is "yTe"
Here is the code that you looking:
var middleName :String? = "some thing"
for index in (middleName?.characters.indices)! {
// do some thing with index
}

NSURL errors with caret ^ in string

Attempting to get data on the S&P500 (symbol: ^GSPC) from Yahoo Finance. In playgrounds and scripts, the presence of a caret (^) in the string passed to NSURL errors with "Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, sub code=0x0)". Xcode 6b6 and b7.
Works fine with other ticker symbols (AAPL, MSFT, etc).
Any suggestions for how to get this working?
let symbols:String = "^GSPC"
let financeURL:String = "http://finance.yahoo.com/d/quotes.csv?s=\(symbols)&f=sl1c6p2"
var financeNSURL: NSURL = NSURL(string: financeURL) // ERROR (see above)
let tickerNSData: NSData = NSData(contentsOfURL: financeNSURL)
var output:NSString = NSString(data:tickerNSData, encoding:NSUTF8StringEncoding)
It's crashing because Swift (at least in Xcode6-Beta7) doesn't support returning nil from an object initializer. From the release notes:
Swift does not support object initializers that fail by returning
null. (16480364)
Workaround: If there is a factory method, use it instead. Otherwise,
capture the result in an optional. For example:
let url: NSURL? = NSURL(string: "not a url")
So, to avoid a crash, declare your financeNSURL as NSURL? (as in the example from the docs above), or use NSURL.URLWithString() instead of init(string:).
However, the root of the problem is that you're not encoding your URL parameters correctly.
If you call stringByAddingPercentEncodingWithAllowedCharacters(...) on symbols it works:
let symbols:String = "^GSPC".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
let financeURL:String = "http://finance.yahoo.com/d/quotes.csv?s=\(symbols)&f=sl1c6p2"
let financeNSURL: NSURL? = NSURL(string: financeURL)
if let url = financeNSURL {
let tickerNSData: NSData = NSData(contentsOfURL: url)
var output:NSString = NSString(data:tickerNSData, encoding:NSUTF8StringEncoding)
}
Output:
"^GSPC",1999.83,"-2.45","-0.12%"
When creating a NSURLwith init method NSURLWithString: the parameter URLString must be a properly encoded URL string. Your's is not. So, what is this a "properly encoded URL string"?
The corresponding official documentation gives a few more hints where to read:
"URLString: The URL string with which to initialize the NSURL object. This URL string must conform to URL format as described in RFC 2396, and must not be nil. This method parses URLString according to RFCs 1738 and 1808."
(links are mine).
So basically, you need to separately encode each URL component from your source string component using the correct variant of the percent encoding algorithm. Then, compose all encoded string components to the final URL string.
This can be tedious and is certainly error prone. Thus, since iOS 8 there is NSURLComponents (see docs here) which can aid you in this task.

Resources