Swift App Extension: instance method count is unavailable - ios

I just create my first app extension using XCode 7.1. One code file containing the code below is shared with both targets:
var str = "";
var l = str.count; //Compile error for extension target App: count is unavailable: There is no ...
The reason for this compile error seams to be that App extension compiles with swift 1.2 while the container target compiles with swift 2.0.
One solution would be importing the content App into the extension App doesn't appear to be a good solution from what i read about it. Sharing the code between targets can be difficult if both are not compiled using the same compiler.
I just run through all target settings and didn't find nothing that could be changed.
Can't find any post about this problem, witch is not so uncommon, so it is must likely i am interpreting something in a wrong way.
The only solution i can think of is using NSString instead of String but that is just an workaround for one class type. More problems of this kind will emerge in the future.

In Swift 2 it's
str.characters.count

Use str.characters.count to get String length in Swift 2

Related

Issue with String initializer in Swift when using format parameter

I'm getting an error for this line of Swift code in my XCode playground:
print(String(format: "%.2f", 3.345))
The error reads
No exact matches in call to initializer
I believe this means that I haven't used the right parameter names/order to call the initializer. However, when running this line of code while working on an iOS app or even in the online Swift playground http://online.swiftplayground.run/, the line runs without any issues.
When running it in the XCode playground or on my terminal through the Swift REPL however, it throws an error.
Why is this the case?
Foundation has to be imported before using String.
String is a Foundation type in swift.
I was corrected by Matt below in the comments.
String is built into swift and String(format: is in foundation.
I guess that's why the docs didn't show it as such.
Thank you for the correction.

Realm crash on iOS 10 with 'String'

I have recently released a new version of our app and during beta testing, it's crashing on all iOS 10 devices but not other versions. Since we have Crashlytics, we found a strange crash message in the backend that we can confirm is the reason all iOS 10 crashing since it's 100% iOS 10 and there's like 40 of them.
It reads as follows:
Fatal Exception: RLMException
Property Article.id is declared as String, which is not a supported managed Object property type. If it is not supposed to be a managed property, either add it to ignoredProperties() or do not declare it as #objc dynamic. See https://realm.io/docs/swift/latest/api/Classes/Object.html for more information.
And here's the object:
class Article: Object {
#objc dynamic var id: String = UUID().uuidString
// others...
override static func primaryKey() -> String? {
return "id"
}
}
As you can see, this is perfectly nomral and runs fine on other iOS. In Realm's doc, it LITERALLY SAYS to use String with #objc dynamic and there's no way it's unsupported. I suspect there's nothing special about Article.id, and since Article starts with A, it happens to be the first String property of all realm Objects. Maybe somehow all Strings stopped working on iOS 10?
Can anyone offer some advice or insights?(Please don't say things like drop iOS 10 support. For now, we need it.)
We ran into the same issue a couple of times, trying to drag Realm fully into Swift. This is not really the answer but more of a workaround we've had success with when needing backward compatibility.
It's an ObjC object, not Swift.
There's something going on with the bridging, perhaps conforming to NSCopy'ing or something along those line, so just change it to read
#objc dynamic var id = NSUUID().uuidString
See the Getting Started Guide in the Models section which calls for using NSUUID
NSUUID: An object representing a universally unique value that bridges
to UUID; use NSUUID when you need reference semantics or other
Foundation-specific behavior.
Turns out it was a Realm's bug. We happen to have another app that runs just fine on iOS 10, and after some inspection we realized that it was using Realm 4.3.2, instead of 4.4.1. After we downgraded Realm to 4.3.2, this problem disappeared.

Not able to use Kotlin Extension Function written in common in iOS as Swift Extension

I have a Kotlin Multiplatform project setup with Android & cocoapods for iOS.
I have a file Extensions.kt in commonMain/src with the following function:
fun String.isValidEmail(): Boolean {
return validate(ValidatorRegex.EMAIL)
}
I am able to access this function in Android as a String extension:
"abcd#gmail.com".isValidEmail()
But in iOS using Swift, I need to call it as a static method of another class:
ExtensionsKt.isValidEmail("abcd#gmail.com")
It should convert that commonMain/src method to a Swift extension of String instead of a class with a static method.
Am I missing any configuration?
You're doing everything right here. Unfortunately, this option is not available for now. Extensions conversion may be performed correctly for some classes, but Swift's String is not the one. This is a known inconvenience, and K/N team is working hard to make it better.

NSAttributedStringKey.attachment versus NSAttachmentAttributeName

I'm having problems with NSAttributedStringKey.attachment versus NSAttachmentAttributeName. Here's the relevant code:
var key: Any?
if #available(iOS 11, *) {
key = NSAttributedStringKey.attachment
}
else {
key = NSAttachmentAttributeName
}
One of two things are happening. In the actual place where I'm trying to use this code (a Cococapod of my own design, with a deployment target of iOS 8 and now building with Xcode 9), I get an error:
Type 'NSAttributedStringKey' (aka 'NSString') has no member 'attachment'
Or, if I just make a new example project and set the deployment target at iOS 8, I get:
'NSAttachmentAttributeName' has been renamed to 'NSAttributedStringKey.attachment'
This is not the behavior I'd expect with #available. Thoughts?
This String vs struct difference is between Swift 3 (uses Strings such as NSAttachmentAttributeName) and Swift 4 (uses struct static attributes such as NSAttributedStringKey.attachment), not between iOS <11 and iOS >=11. For instance, you can use NSAttributedStringKey.attachment and similar in any supporting version of iOS (e.g. .attachment is available since iOS 7) within a Swift 4 project. #available doesn't apply because it's a Swift language version difference rather than an OS version difference.
Ensure your pod is set to the correct Swift version and it should then work as expected. You can tell CocoaPods that by adding a .swift-version file at the top of your project:
$ echo 4.0 >.swift-version
This magical version file is mentioned in passing in a CocoaPods blog post from last year: http://blog.cocoapods.org/CocoaPods-1.1.0/

Parse SDK and Swift: Incorrect argument label in call PFObject 'withoutDataWithObjectId'

I subclass PFObject exactly as described here.
Then I create a new instance of the subclassed object without data, but since Swift 1.2 I get an error (It did work perfectly before):
var test = Armor(withoutDataWithObjectId: "1234567890")
-> Xcode complains:
"Incorrect argument label in call (have 'withoutDataWithObjectId:',
expected: 'className:')"
Why className? It should get the class name from the class function parseClassName
And I can under no circumstances create a new object with objectId but no data (which I MUST have to fetch it from the local datastore)
This is super annoying as my app doesn't compile any longer.
Update to the newest Parse SDK, available here.
The issue is caused due to necessary adaptions in the Parse SDK after the Swift language update. This issue also occurs with the most recent update to Swift 2.2. The newest (as of today) Parse SDK release 1.13.0 already fixes this.
UPDATE
Parse iOS SDK 1.13.0 has a typo and the function PFUser(withoutDataWithObjectId:) is called PFUser(outDataWithObjectId:). So upgrading the Parse SDK alone does solve this. Until this is fixed a temporary workaround would be to extend PFObject with a convenience initializer. To do this add a new Swift file to your project and insert this:
import Parse
extension PFObject {
convenience init(withoutDataWithObjectId objectId: String?) {
self.init(outDataWithObjectId: objectId)
}
}
It may be a little late to answer this question.
I use swift 1.2, and v 1.7.5 Parse SDK, and it works totally fine.
however, make sure you have define objective-c bridging header in "build setting".
and try to run it, even though there may reports some error

Resources