Cannot invoke 'SecPolicyCreateSSL' with an argument list of type '(Bool, String?)' - swift2

HTTPSecurity.swift:124:22: Cannot invoke 'SecPolicyCreateSSL' with an argument list of type '(Bool, String?)'
I'm getting the above error when trying to build a project containing this code:
public func isValid(trust: SecTrustRef, domain: String?) -> Bool {
var tries = 0
while(!self.isReady) {
usleep(1000)
tries += 1
if tries > 5 {
return false //doesn't appear it is going to ever be ready...
}
}
var policy: SecPolicyRef
if self.validatedDN {
policy = SecPolicyCreateSSL(true, domain)
} else {
policy = SecPolicyCreateBasicX509()
}
SecTrustSetPolicies(trust,policy)
if self.usePublicKeys {
if let keys = self.pubKeys {
var trustedCount = 0
let serverPubKeys = publicKeyChainForTrust(trust)
for serverKey in serverPubKeys as [AnyObject] {
for key in keys as [AnyObject] {
if serverKey.isEqual(key) {
trustedCount++
break
}
}
}
if trustedCount == serverPubKeys.count {
return true
}
}
} else if let certs = self.certificates {
let serverCerts = certificateChainForTrust(trust)
var collect = Array<SecCertificate>()
for cert in certs {
if let c = SecCertificateCreateWithData(nil,cert) {
collect.append(c)
}
}
SecTrustSetAnchorCertificates(trust,collect)
var result: SecTrustResultType = 0
SecTrustEvaluate(trust,&result)
let r = Int(result)
if r == kSecTrustResultUnspecified || r == kSecTrustResultProceed {
var trustedCount = 0
for serverCert in serverCerts {
for cert in certs {
if cert == serverCert {
trustedCount++
break
}
}
}
if trustedCount == serverCerts.count {
return true
}
}
}
return false
}
This code is from:
https://github.com/mpclarkson/SwiftHTTP/blob/swift-2/HTTPSecurity.swift#L124

Method using old fashion Boolean which is in fact UInt8. Method also use CFString and not String.
Easy solution is following:
policy = SecPolicyCreateSSL(1, domain as CFString)
More sophisticated solution is use extension for Bool:
extension Bool {
var booleanValue : Boolean {
return self ? 1 : 0
}
init(booleanValue : Boolean) {
self = booleanValue == 0 ? false : true
}
}
Then you can use:
policy = SecPolicyCreateSSL(true.booleanValue, domain as CFString)

Related

MacCatalyst VPN Connection Ask Password Each Connection

When we try to connect with MacCatalyst, the system asks for a password every connection, but when working on a project created for only MacOS, it connects directly without asking for a password. The output of the “set” functions in the KeychainWrapper class is the same for both projects, but when I compare both keys in keychain access, there are differences as show in the attachment and my codes
Keychain Screenshot
Here is my IKEv2 connection codes:
public func connectIKEv2(config: Configuration, onError: #escaping (String)->Void) {
let p = NEVPNProtocolIKEv2()
p.authenticationMethod = NEVPNIKEAuthenticationMethod.none
p.deadPeerDetectionRate = NEVPNIKEv2DeadPeerDetectionRate.medium
p.disableRedirect = false
p.enableRevocationCheck = false
p.enablePFS = false
p.useExtendedAuthentication = true
p.remoteIdentifier = config.server
p.useConfigurationAttributeInternalIPSubnet = false
p.serverAddress = config.server
p.username = config.account
p.passwordReference = config.getPasswordRef()
loadProfile { _ in
self.manager.protocolConfiguration = p
self.manager.onDemandRules = [NEOnDemandRuleConnect()]
self.manager.isOnDemandEnabled = true
self.manager.isEnabled = true
self.saveProfile { success in
if !success {
onError("Unable to save vpn profile")
return
}
else {
print("Mayank: Profile saved")
}
self.loadProfile() { success in
if !success {
onError("Unable to load profile")
return
}
let result = self.startVPNTunnel()
if !result {
onError("Can't connect")
}
else {
print("Mayank: connecting with result")
print(result)
}
}
}
}
}
Here is KeychainWrapper set functions:
#discardableResult open func set(_ value: String, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
if let data = value.data(using: .utf8) {
return set(data, forKey: key, withAccessibility: accessibility)
} else {
return false
}
}
#discardableResult open func set(_ value: Data, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
var keychainQueryDictionary: [String:Any] = setupKeychainQueryDictionary(forKey: key, withAccessibility: accessibility)
keychainQueryDictionary[SecValueData] = value
if let accessibility = accessibility {
keychainQueryDictionary[SecAttrAccessible] = accessibility.keychainAttrValue
} else {
keychainQueryDictionary[SecAttrAccessible] = KeychainItemAccessibility.whenUnlocked.keychainAttrValue
}
let status: OSStatus = SecItemAdd(keychainQueryDictionary as CFDictionary, nil)
if status == errSecSuccess {
return true
} else if status == errSecDuplicateItem {
return update(value, forKey: key, withAccessibility: accessibility)
} else {
return false
}
}
private func update(_ value: Data, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
var keychainQueryDictionary: [String:Any] = setupKeychainQueryDictionary(forKey: key, withAccessibility: accessibility)
let updateDictionary = [SecValueData:value]
if let accessibility = accessibility {
keychainQueryDictionary[SecAttrAccessible] = accessibility.keychainAttrValue
}
let status: OSStatus = SecItemUpdate(keychainQueryDictionary as CFDictionary, updateDictionary as CFDictionary)
if status == errSecSuccess {
return true
} else {
return false
}
}

Swift 3: What is the alternative for Sequence in Swift 2.3

So Swift 3 adds sequences, the following code works fine in Swift 3 however I am trying to convert it back to Swift 2.3
What would I replace sequence with in swift 2.3?
func isWifiEnabled() -> Bool {
var addresses = [String]()
var ifaddr : UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return false }
guard let firstAddr = ifaddr else { return false }
for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
addresses.append(String(cString: ptr.pointee.ifa_name))
}
freeifaddrs(ifaddr)
return addresses.contains("awdl0")
}
This worked for Swift 2.3 but will of course not work for Swift 3
func isWifiEnabled() -> Bool {
var addresses = [String]()
var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
guard getifaddrs(&ifaddr) == 0 else { return false }
var ptr = ifaddr
while ptr != nil { defer { ptr = ptr.memory.ifa_next }
addresses.append(String.fromCString(ptr.memory.ifa_name)!)
}
var counts:[String:Int] = [:]
for item in addresses {
counts[item] = (counts[item] ?? 0) + 1
}
freeifaddrs(ifaddr)
return counts["awdl0"] > 1 ? true : false
}
Updated
I also noticed that it was listing awdl0 twice? Maybe a new thing to iOS 10.2

Sorting Strings by Character and Length

In my Android app, I am trying to sort Bus route tags in order 1, 2, 3..etc.
For that I am using this
Collections.sort(directions, Comparator { lhs, rhs ->
var obj1 = lhs.short_names.firstOrNull() ?: ""
var obj2 = rhs.short_names.firstOrNull() ?: ""
if (obj1 === obj2) {
obj1 = lhs.headsigns.firstOrNull() ?: ""
obj2 = rhs.headsigns.firstOrNull() ?: ""
if (obj1 === obj2) {
return#Comparator 0
}
obj1.compareTo(obj2)
} else {
obj1.compareTo(obj2)
}
The issue I am having is this sorts them, but will run into the issue of
1, 2, 3, 30, 31, 4, 5
How should I change this to get the correct ordering.
If you need just a simple number comparison you can do it like that.
directions.sortWith(Comparator { lhs, rhs ->
val i1 = lhs.toInt()
val i2 = rhs.toInt()
when {
i1 < i2 -> -1
i1 > i2 -> 1
else -> 0
}
})
As hotkey pointed out the code above can be replaced with almost identical implementation that looks much simplier.
directions.sortBy { it.toInt() }
The general version of this algorithm is called alphanum sorting and described in details here. I made a Kotlin port of this algorithm, which you can use. It's more complicated than what you need, but it will solve your problem.
class AlphanumComparator : Comparator<String> {
override fun compare(s1: String, s2: String): Int {
var thisMarker = 0
var thatMarker = 0
val s1Length = s1.length
val s2Length = s2.length
while (thisMarker < s1Length && thatMarker < s2Length) {
val thisChunk = getChunk(s1, s1Length, thisMarker)
thisMarker += thisChunk.length
val thatChunk = getChunk(s2, s2Length, thatMarker)
thatMarker += thatChunk.length
// If both chunks contain numeric characters, sort them numerically.
var result: Int
if (isDigit(thisChunk[0]) && isDigit(thatChunk[0])) {
// Simple chunk comparison by length.
val thisChunkLength = thisChunk.length
result = thisChunkLength - thatChunk.length
// If equal, the first different number counts.
if (result == 0) {
for (i in 0..thisChunkLength - 1) {
result = thisChunk[i] - thatChunk[i]
if (result != 0) {
return result
}
}
}
} else {
result = thisChunk.compareTo(thatChunk)
}
if (result != 0) {
return result
}
}
return s1Length - s2Length
}
private fun getChunk(string: String, length: Int, marker: Int): String {
var current = marker
val chunk = StringBuilder()
var c = string[current]
chunk.append(c)
current++
if (isDigit(c)) {
while (current < length) {
c = string[current]
if (!isDigit(c)) {
break
}
chunk.append(c)
current++
}
} else {
while (current < length) {
c = string[current]
if (isDigit(c)) {
break
}
chunk.append(c)
current++
}
}
return chunk.toString()
}
private fun isDigit(ch: Char): Boolean {
return '0' <= ch && ch <= '9'
}
}
To use this Comparator just call
directions.sortWith(AlphanumComparator())
If you don't need it to be coded in Kotlin you can just take an original Java version on Dave Koelle's page. And the Kotlin version of the algorithm can be also found on GitHub.

Why is one label updating quicker then the other?

I am making my own Spotify controller to learn how to interact with AppleScript and Swift (using Objective-C as a bridge) to make a bigger project later on. The only issue is the current progress time seems to update slightly faster then the time left.
This is what my application looks like:
The time on the left seems to update slightly faster then the time on the right, this means it is not accurate and can be bit strange to look at. How would I be able to fix this so both the progress time and time left update at the same time?
Here is my code:
ViewController.swift
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var statusLabel: NSTextField!
#IBOutlet weak var songProgress: NSProgressIndicator!
#IBOutlet weak var lblCurrentProgress: NSTextField!
#IBOutlet weak var lblTrackLength: NSTextField!
//let debugger = Debug(appName:"Spotify Menu", debugable: )
var previousScript:String = ""
var toggleScript:String = ""
var nextScript:String = ""
var statusScript:String = ""
var artistScript:String = ""
var songNameScript:String = ""
var trackPosScript:String = ""
var trackLengthScript:String = ""
var trackIDscript:String = ""
var trackName:String = "unknown"
var artistName:String = "unknown"
var playerStatus:String = "unknown"
var trackID:String = "unknown"
var playerPosistion:Double = -1.0
var trackLength:Double = -1.0
var percentThrough:Double = -1.0
let timeFormatter = twoDiffrentTimes()
func main()
{
getStatus()
getSongName()
getArtist()
getTrackLength()
getPlayerPos()
getID()
percentThrough = (playerPosistion/trackLength)*100
if(playerStatus == "playing" && trackName != "unknown" && artistName != "unknown")
{
statusLabel.stringValue = "Spotify is currently playing the song \"\(trackName)\" by \"\(artistName)\""
} else if(playerStatus == "paused"){
statusLabel.stringValue = "Spotify is currently paused"
} else if(playerStatus == "stopped") {
statusLabel.stringValue = "Spotify is not playing any music"
} else {
statusLabel.stringValue = "There is currently an error"
}
//NSLog("The song is currently \(percentThrough.toDecimalPlace("2"))% the way in")
songProgress.doubleValue = percentThrough
timeFormatter.update(playerPosistion, timeTwo: trackLength-playerPosistion)
lblCurrentProgress.stringValue = timeFormatter.timeOneString
lblTrackLength.stringValue = timeFormatter.timeTwoString
}
override func viewDidLoad() {
super.viewDidLoad()
previousScript = readFile("previousTrack")
if(previousScript == "")
{
NSLog("Error finding previous track script")
exit(1)
}
toggleScript = readFile("playPause")
if(toggleScript == "")
{
NSLog("Error finding toggle script")
exit(1)
}
nextScript = readFile("nextTrack")
if(nextScript == "")
{
NSLog("Error going forwared a track")
exit(1)
}
statusScript = readFile("playerStatus")
if(statusScript == "")
{
NSLog("Error going back a track")
statusLabel.stringValue = "Spotify is in an unknown status"
exit(1)
}
artistScript = readFile("getArtist")
if(artistScript == "")
{
NSLog("Cannot get artist script")
exit(1)
}
songNameScript = readFile("getSongName")
if(songNameScript == "")
{
NSLog("Cannot get song name script")
exit(1)
}
trackPosScript = readFile("playerPosition")
if(trackPosScript == "")
{
NSLog("Error getting track posistion script")
exit(1)
}
trackLengthScript = readFile("durationOfSong")
if(trackLengthScript == "")
{
NSLog("Error getting track length script")
exit(1)
}
trackIDscript = readFile("trackID")
if(trackIDscript == "")
{
NSLog("Error getting")
}
main()
NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: Selector("main"), userInfo: nil, repeats: true)
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func previous(sender: AnyObject)
{
runAppleScript(previousScript)
}
#IBAction func toggle(sender: AnyObject)
{
runAppleScript(toggleScript)
}
#IBAction func next(sender: AnyObject)
{
let nextFile = readFile("nextTrack")
if(nextFile == "")
{
NSLog("Error going forwared a track")
} else {
runAppleScript(nextFile)
}
}
func getPlayerPos()
{
playerPosistion = runAppleScript(trackPosScript).toDouble()
}
func getTrackLength()
{
trackLength = runAppleScript(trackLengthScript).toDouble()
}
func getSongName()
{
trackName = runAppleScript(songNameScript)
}
func getArtist()
{
artistName = runAppleScript(artistScript)
}
func getID()
{
trackID = runAppleScript(trackIDscript)
}
func getStatus()
{
let resultData = runAppleScript(statusScript)
if(resultData == "playing" || resultData == "paused" || resultData == "stopped")
{
playerStatus = resultData
} else {
playerStatus = "unknown"
}
}
}
classes.swift
import Foundation
class twoDiffrentTimes
{
var timeOne:Double = 0.0
var iMinuteOne:Int = 0
var iSecondsOne:Int = 0
var minuteOne:String = ""
var secondsOne:String = ""
var timeOneString:String = ""
var uSecondsOne:Double = 0.0
var temp:Int = 0
var timeTwo:Double = 0.0
var iMinuteTwo:Int = 0
var iSecondsTwo:Int = 0
var minuteTwo:String = ""
var secondsTwo:String = ""
var timeTwoString:String = ""
var uSecondsTwo:Double = 0.0
func update(timeOne:Double, timeTwo:Double)
{
//First Time
self.temp = Int(timeOne)
self.iMinuteOne = temp / 60
self.iSecondsOne = temp % 60
self.minuteOne = "\(iMinuteOne)"
if(self.iSecondsOne < 10)
{
self.secondsOne = "0\(self.iSecondsOne)"
} else {
self.secondsOne = "\(self.iSecondsOne)"
}
self.timeOneString = "\(self.iMinuteOne).\(self.secondsOne)"
//Second Time
self.temp = Int(timeTwo)
self.iMinuteTwo = temp / 60
self.iSecondsTwo = temp % 60
self.minuteTwo = "\(iMinuteTwo)"
if(self.iSecondsTwo < 10)
{
self.secondsTwo = "0\(self.iSecondsTwo)"
} else {
self.secondsTwo = "\(self.iSecondsTwo)"
}
self.timeTwoString = "\(self.iMinuteTwo).\(self.secondsTwo)"
}
}
extensions.swift
import Foundation
extension String {
func toDouble() -> Double {
if let unwrappedNum = Double(self) {
return unwrappedNum
} else {
// Handle a bad number
print("Error converting \"" + self + "\" to Double")
return 0.0
}
}
}
extension Double {
func toDecimalPlace(f: String) -> String {
return NSString(format: "%0.\(f)f", self) as String
}
func decimalValue() -> Int
{
if let decimalString = String(self).componentsSeparatedByString(".").last, decimal = Int(decimalString) {
return decimal // 535
} else {
return -1
}
}
}
functions.swift
import Foundation
func readFile(fileName: String) -> String{
if let filepath = NSBundle.mainBundle().pathForResource(fileName, ofType: "txt") {
do {
let contents = try NSString(contentsOfFile: filepath, usedEncoding: nil) as String
print(contents)
return contents
} catch {
NSLog("Content Could Not Be Loaded")
return ""
}
} else {
NSLog("File \(fileName).\("txt") could not be found")
return ""
}
}
func runAppleScript(script:String) -> String
{
let theResult:String
let errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()
let startAtLoginScript: NSAppleScript = NSAppleScript(source: script)!
let theDiscriptor:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(errorInfo)
if let _ = theDiscriptor.stringValue
{
theResult = theDiscriptor.stringValue!
} else {
theResult = ""
}
return theResult
}
errorClases.swift
import Foundation
enum MyAppleScriptError: ErrorType {
case ExecutingScriptFailed
case GettingStringValueFailed
}
Last but not least durationOfSong.txt (AppleScript)
tell application "Spotify"
set songLength to (duration of current track) / 1000 as string
return songLength
end tell
And playerPosition
tell application "Spotify"
set currentPosistion to player position as string
return currentPosistion
end tell
Edit:
Updated code
I recommend you learn how to call AppleScript handlers directly from Swift via the AppleScript-ObjC bridge. That will work vastly better than mucking about with code strings and NSAppleScript, which is slow and nasty and not a good way to do it. Tutorial here:
http://macscripter.net/viewtopic.php?id=43127
--
ETA:
"I have successful moved NSAppleScript to Swift2. Only thing is that still doesn't fix the issue. it is still out of timing."
Well, that's annoying. FWIW, I'd ditch that twoDiffrntTimes class as it doesn't do anything that can't be done in a single-line function, and change the end of main() to this:
func main() {
...
lblCurrentProgress.stringValue = formatTime(Int(playerPosistion))
lblTrackLength.stringValue = formatTime(Int(trackLength-playerPosistion))
}
func formatTime(secs: Int) -> String {
return NSString(format: "%i.%02i", secs / 60, secs % 60) as String
}

LinearSeqOptimized#find Reference Copy

Looking at the Scala 2.10.0's implementation of LinearSeqOptimized#find in LinearSeqOptimized.scala, why is it necessary to call var these = this?
Why couldn't this simply be used?
override /*IterableLike*/
def find(p: A => Boolean): Option[A] = {
var these = this
while (!these.isEmpty) {
if (p(these.head)) return Some(these.head)
these = these.tail
}
None
}
Because you would have to have the same condition and operation out of the loop for this and then start using these.
It's much simpler to just put everyone in the same basket and do it all in the loop itself. Example:
def find(p: A => Boolean): Option[A] = {
if (!this.isEmpty && p(this.head)) {
return Some(this.head)
}
var these = this.tail
while (!these.isEmpty) {
if (p(these.head)) return Some(these.head)
these = these.tail
}
None
}
Not very smart, as you can see.
You could also easily implement this as a #tailrec operation:
#tailrec final def find[A](p : A => Boolean) : Option[A] = {
if ( this.isEmpty ) {
None
} else {
if ( p(this.head) ) {
Some(this.head)
} else {
this.tail.find(p)
}
}
}
And it isn't done like this in Scala because tailrec calls have to be final or private.

Resources