Swift and Foundation relationship - ios

As a newcomer to iOS Development i want to understand the relationship between Swift 2 and Foundation Framework
I already know that Swift is just a programming language and Foundation is a framework build on Objective-C.
What i don't understand is when i need to use Foundation classes or just stay at pure Swift.
For eg. when i have a Swift string do i always need to inherit from NSString for functionality i can't find in pure Swift strings?
Yesterday i was looking for a case-insensitive comparison between two Swift string. One of the solutions i found was that:
var a : String = "Cash"
var b : String = "cash"
if(a.caseInsensitiveCompare(b) == NSComparisonResult.OrderedSame){
println("voila")
}
This bring me a lot of frustration. How can a Swift string has a function(caseInsensitiveCompare) that doesn't exist in pure Swift?
Did the string inherit it from somewhere and how?
Please give me an overall explanation for when i need the foundation as a superset of Swift. Which part of foundation are no longer needed by me as a developer who skip Objective-C for Swift?

How can a Swift string has
a function(caseInsensitiveCompare) that doesn't exist in pure Swift?
It's because you imported Foundation (or UIKit, which includes Foundation) and because Swift String is bridged to Foundation NSString. This causes many (but not all) NSString methods to spring to life for String.
If you had not imported Foundation, you would not have been able to do what you did: caseInsensitiveCompare would not have been present.

The Foundation framework has its roots in NeXTSTEP, from the early days of Objective C. It's a great framework, but admittedly it's dated and lacks a lot of modern programming principles, and doesn't take advantage of many of Swift's new shiny toys. Apple is working on revitalizing Foundation for Swift 3.
I would steer clear of using Foundation anytime a pure Swift solution is available.
In your case, you can do case-insensitive comparison by converting both strings to lower case and comparing them:
if a.lowercaseString == b.lowercaseString {
//Strings match
}
I would actually roll it into an extension of String:
extension String {
func equalsIgnoringCase() -> Bool {
return a.lowercaseString == b.lowercaseString
}
}
//then:
if a.equalsIgnoringCase(b) {
//Strings match
}

Related

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.

Swift App Extension: instance method count is unavailable

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

How to import a project into Xcode

I am attempting to integrate the Yelp API into my iOS app. From the existing yelp documentation for objective C, we downloaded their Xcode project and dragged it into our project. However, when trying to call and import the project in my swift file, we have errors. Here is what I mean:
func getYelpData(mapItem:MKMapItem) {
var term: String = (NSUserDefaults.standardUserDefaults().valueForKey("term") ?? "") as! String;
var location: String = (NSUserDefaults.standardUserDefaults().valueForKey("location") ?? "") as! String
var APISample: YPAPISample = YPAPISample() // Use of undeclared type 'YPAPISample'
and at the top of the class I try to import the YPAPISample like so
import YelpAPISample
but it does not allow me to do this either.
I'm new to swift programming so any help would be greatly appreciated!
It's one of the most regularly asked question regarding Swift on SO.
Apple provided a document here for such purpose:
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
In short, you'd need to create a bridge header to import the Objective-C framework. Not all the framework can be import directly in Swift.
To add it manually, search bridging in build settings: (Make sure you select All)

How to use the CoreAudio API in Swift

I am in the process of migrating my streaming audio engine to swift. i am finding it difficult to use the C Audio API in swift.
I have a problem with AudioFileStreamOpen api where it takes 2 C functions as a parameter. I don't know how to use this API is swift.
AudioFileStreamOpen(self as UnsafePointer<()>, propertyProc, packetProc, kAudioFileMP3Type, audioStreamId)
I have defined the callback method as below for this API. But i am getting the compilation error.
func propertyProc(inClientData: UnsafePointer<()>,inFileStreamId: AudioFileStreamID,inPropertyId: AudioFileStreamPropertyID,ioFlags: UnsafePointer<UInt32>) -> Void {
.....
}
func packetProc(inClientData: UnsafePointer<()>,inNumberOfBytes: UInt32,inNumberOfPackets: UInt32, ConstUnsafePointer<()>, inPacketDescriptions: UnsafePointer<AudioStreamPacketDescription>) -> Void {
.....
}
Any help is appreciated to correctly define this C API in swift
You can't (currently) use an API requiring a C callback pointer from pure Swift code. Calling Swift functions or methods using a C function pointer is not supported by the current beta 4 language implementation, according to replies in the Swift forum at devforums.apple.com
UPDATE: The above answer is obsolete as of Swift 2.0
One alternative is to put some small trampoline C callback functions in an Objective C file, which can interoperate with Swift, and have those C functions in turn call a block or closure, which can be in Swift code. Configure the C callbacks with your Swift closures, and then pass those C callbacks to the CoreAudio functions.
I don't know much about Audio API, however, you should replace UnsafePointer by a pointer to an Object. for example:
var clientData : AnyObject?
var listenerProc : AudioFileStream_PropertyListenerProc = AudioFileStream_PropertyListenerProc.convertFromNilLiteral()
var packetsProc : AudioFileStream_PacketsProc = AudioFileStream_PacketsProc.convertFromNilLiteral()
var audioFileTypyeId : AudioFileTypeID = 0
AudioFileStreamOpen(&clientData, listenerProc, packetsProc, audioFileTypyeId, &streamId)
the initialization code for listenerProc, packetsProc or other variables is just to by-pass the compiler error.
To your situation, try to replace 'self as UnsafePointer<>' by '&self'. However 'self' must be something that can be converted to compatible data type.
https://developer.apple.com/library/prerelease/ios/documentation/MusicAudio/Reference/AudioStreamReference/index.html#//apple_ref/c/func/AudioFileStreamOpen

Where can I find the "math, strings, etc... libraries" for Swift?

I am looking at the Swift documentation, but I can't find reference to what there's in other languages...
Examples: sin(), cos(), abs() for math, uppercase(), lowercase() for strings, sort(), pop(), push() for arrays etc...
For strings I've found this in the docs:
Swift’s String type is bridged seamlessly to Foundation’s NSString
class. If you are working with the Foundation framework in Cocoa or
Cocoa Touch, the entire NSString API is available to call on any
String value you create, in addition to the String features described
in this chapter. You can also use a String value with any API that
requires an NSString instance.
Could you point me to some doc or where can I find those functions listed?
Looks like this is working...
import Foundation
var theCosOfZero: Double = Double(cos(0)) // theCosOfZero equals 1
The math functions are defined in the Darwin module, so as absolute minimum you have add this:
import Darwin
In most cases import Foundation or import Cocoa will suffice, since those modules import the Darwin module. If you need access to constants like M_PI or similar, navigate with cmd+click to the Darwin module and the to the Darwin.C. Here you would find the C API imports and the Darwin.C.math among them. This way you may examine what's available, already converted to Swift. Nevertheless, all that C API is available with import Darwin.
You cannot issue import Darwin.C.math directly, because you will see the following runtime error (or similar if you're not in the playground):
Playground execution failed: Error in auto-import:
failed to get module 'math' from AST context
Example playground code:
import Darwin
func degToRad(degrees: Double) -> Double {
// M_PI is defined in Darwin.C.math
return M_PI * 2.0 * degrees / 360.0
}
for deg in 0..<360 {
sin(degToRad(Double(deg)))
}
sin(), cos(), abs() are C methods defined in math.h https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/math.3.html
"str".uppercaseString() and "str".lowercaseString() are NSString methods.
sort() is part of the Swift Standard Library, documented at https://developer.apple.com/documentation/swift/array/1688499-sort
Array.append() and Array.removeLast() are also defined in the Swift Standard Library, documented at https://developer.apple.com/documentation/swift/array

Resources