标签: swift4

Swift 4:NSFilenamesPboardType不可用.使用什么代替registerForDraggedTypes?

迁移到Swift4后,以下代码引发编译错误:

public final class MediaItemView: NSView {

   public override init(frame frameRect: NSRect) {
      super.init(frame: frameRect)

      // error: 'NSFilenamesPboardType' is unavailable in Swift:
      // use 'NSPasteboard.writeObjects(_:)' with file URLs
      let draggedTypes: [NSPasteboard.PasteboardType] = [NSFilenamesPboardType]
      registerForDraggedTypes(draggedTypes)
   }
}
Run Code Online (Sandbox Code Playgroud)

什么是NSFilenamesPboardTypeSwift4 的替代品?如何file name在Swift4中注册拖动类型(在我的情况下是mp3,wav,aiff,...文件)?

谢谢!

macos cocoa drag-and-drop swift swift4

13
推荐指数
4
解决办法
4040
查看次数

Swift 4中的String,substring,Range,NSRange

我使用以下代码String从以下代码获取子字符串NSRange:

func substring(with nsrange: NSRange) -> String? {
    guard let range = Range.init(nsrange)
        else { return nil }
    let start = UTF16Index(range.lowerBound)
    let end = UTF16Index(range.upperBound)
    return String(utf16[start..<end])
}
Run Code Online (Sandbox Code Playgroud)

(来自:https://mjtsai.com/blog/2016/12/19/nsregularexpression-and-swift/)

当我编译与斯威夫特4(9B4的Xcode),我获取该声明两条线以下的错误startend:

'init' is unavailable
'init' was obsoleted in Swift 4.0
Run Code Online (Sandbox Code Playgroud)

我很困惑,因为我没有使用init.

我怎样才能解决这个问题?

string range nsrange swift4

13
推荐指数
2
解决办法
1万
查看次数

测试一个CharacterSet是否在Swift 4中包含一个字符的最佳方法是什么?

我正在寻找一种方法,在Swift 4中,测试一个Character是否是一个任意CharacterSet的成员.我有这个Scanner类将用于一些轻量级的解析.该类中的一个功能是跳过当前位置的属于某组可能字符的任何字符.

class MyScanner {
  let str: String
  var idx: String.Index
  init(_ string: String) {
    str = string
    idx = str.startIndex
  }
  var remains: String { return String(str[idx..<str.endIndex])}

  func skip(charactersIn characters: CharacterSet) {
    while idx < str.endIndex && characters.contains(str[idx])) {
      idx = source.index(idx, offsetBy: 1)
    }
  }
}

let scanner = MyScanner("fizz   buzz fizz")
scanner.skip(charactersIn: CharacterSet.alphanumerics)
scanner.skip(charactersIn: CharacterSet.whitespaces)
print("what remains: \"\(scanner.remains)\"")
Run Code Online (Sandbox Code Playgroud)

我想实现该skip(charactersIn:)功能,以便打印上面的代码buzz fizz.

最棘手的部分是characters.contains(str[idx]))while- .contains()需要Unicode.Scalar,我不知所措,试图找出下一步骤.

我知道我可以在一传String …

swift swift4

13
推荐指数
3
解决办法
8652
查看次数

强制转换,即使协议需要给定类型

我有以下代码:

import UIKit

protocol Fooable: class where Self: UIViewController {
    func foo()
}

class SampleViewController: UIViewController, Fooable {

    func foo() {
        print("foo")
    }
}

let vc1: Fooable = SampleViewController()
let vc2: Fooable = SampleViewController()


// vc1.show(vc2, sender: nil) - error: Value of type 'Fooable' has no member 'show'

// (vc1 as! UIViewController).show(vc2, sender: nil) - error: Cannot convert value of type 'Fooable' to expected argument type 'UIViewController'

(vc1 as! UIViewController).show((vc2 as! UIViewController), sender: nil)
Run Code Online (Sandbox Code Playgroud)

注释行不编译.

为什么UIViewController即使Fooable协议需要,我也被迫将协议类型对象强制转换为符合它的类型继承 …

swift swift4

13
推荐指数
2
解决办法
657
查看次数

Swift 4使用KVO收听音量变化

我刚刚更新到Swift 4和Xcode 9并得到(swiftlint)警告,以下代码告诉我现在应该使用KVO:

警告:

(基于块的KVO违规:在使用Swift 3.2或更高版本时,首选基于新块的KVO API和键路径.(block_based_kvo))

旧代码:

override func observeValue(forKeyPath keyPath: String?,
                           of object: Any?,
                           change: [NSKeyValueChangeKey : Any]?,
                           context: UnsafeMutableRawPointer?) {
    if keyPath == "outputVolume"{
        guard let newKey = change?[NSKeyValueChangeKey.newKey] as? NSNumber else {
            fatalError("Could not unwrap optional content of new key")
        }

        let volume = newKey.floatValue

        print("volume " + volume.description)
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试修复:

let audioSession = AVAudioSession.sharedInstance()
    audioSession.observe(\.outputVolume) { (av, change) in
        print("volume \(av.outputVolume)")
}
Run Code Online (Sandbox Code Playgroud)

Apple 在这里声称大多数属性应该是dynamic(我知道这是AVPlayer而不是AVAudioSession).我查了一下,但dynamic在AVPlayer属性中找不到任何声明,并想知道它是如何工作的(如果我没有弄错,那些是KVO工作所必需的).

编辑:

我不确定它是否不会触发,因为它根本不起作用或者是由于我尝试归档的原因.总的来说,我希望通过推动硬件音量摇杆来获得有关音量变化的通知.

key-value-observing ios swiftlint swift4 xcode9

13
推荐指数
2
解决办法
4766
查看次数

无法从角落4快速插入法律归属

我是Xcode和移动应用程序的新手.我正在做一个应用程序来查找当前位置.我在模拟器上测试了它并在控制台中得到了这条消息."无法在角落4处插入法律归属".它是什么意思,我该如何解决?

import UIKit
import Alamofire
import AlamofireImage
import MapKit
import CoreLocation

class MapVC: UIViewController

@IBOutlet weak var mapView: MKMapView!

var locationManager = CLLocationManager()
let authorizationStatus = CLLocationManager.authorizationStatus()
let regionRadius: Double = 1000

override func viewDidLoad() {
    super.viewDidLoad()

    mapView.delegate = self
    locationManager.delegate = self
    configureLocationServices()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func centerMapPressed(_ sender: Any) {
    if authorizationStatus == .authorizedAlways || authorizationStatus == .authorizedWhenInUse{
        centerMapOnUserLocation()
    }
}
Run Code Online (Sandbox Code Playgroud)

MKMapViewDelegate:

func centerMapOnUserLocation(){ …
Run Code Online (Sandbox Code Playgroud)

ios swift4

13
推荐指数
1
解决办法
1万
查看次数

swift中的线程安全单例

我有和应用程序有一个单一的存储整个应用程序的信息.但是,当使用来自不同线程的单例时,这会产生一些数据争用问题.

这里有一个非常虚拟和简单化的问题版本:

独生子

class Singleton {
    static var shared = Singleton()

    var foo: String = "foo"
}
Run Code Online (Sandbox Code Playgroud)

单例的使用(为简单起见,来自AppDelegate)

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        DispatchQueue.global().async {
            var foo = Singleton.shared.foo // Causes data race
        }

        DispatchQueue.global().async {
            Singleton.shared.foo = "bar"   // Causes data race
        }

        return true
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法确保单例是线程安全的,所以它可以在应用程序的任何地方使用,而不必担心你在哪个线程?

这个问题不是在Swift使用dispatch_once单例模型的重复,因为(如果我理解正确的话)那里他们正在解决访问单例对象本身的问题,但不能确保其属性的读写完成线程安全.

thread-safety swift swift4

13
推荐指数
1
解决办法
3994
查看次数

可解码 - 继承阻止解码器init合成

我有以下Swift 4 Codable类,它继承自Realm的Object类型:

final class SearchResult: RealmSwift.Object, Codable {
    @objc dynamic var name: String = ""
    @objc dynamic var region: String = ""

    enum CodingKeys: String, CodingKey {
        case name = "name"
        case region = "region"
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的期望是该init(from decoder: Decoder)方法被合成,所以我不必自己实现它,这是一个巨大的便利.但是,不实现这会产生以下编译器错误:

super.init isn't called on all paths before returning from initializer

有三种方法可以摆脱编译器错误,但没有一种方法是好的:

  1. 实现一个init(from decoder: Decoder)只调用的空方法super.init().这似乎阻止了合成,意味着没有任何实际解码,因为它只是一个空方法.

  2. init(from decoder: Decoder)手动实现整个方法.这有效,但现在使用的乐趣Codable几乎消失了.

  3. 删除所有与Realm相关的代码.现在Codable按预期工作,但是,现在我不能再使用Realm了.

这对我来说似乎是一个Swift错误,因为它应该检测到init(from decoder: Decoder)实际上是在实现,而不是手动执行.

我不知道的任何建议或解决方法?

realm swift swift4 codable

12
推荐指数
1
解决办法
1102
查看次数

iOS 11搜索栏跳到屏幕顶部

我有一个UITableView,我将其标题设置为搜索栏.

tableView.tableHeaderView = searchController.searchBar
Run Code Online (Sandbox Code Playgroud)

一切都按计划工作,直到你点击它,它似乎脱离tableView并跳转到屏幕的顶部.tableView行保持不变.有什么理由在iOS 11而不是iOS 10中这样做吗?

uitableview ios swift4 ios11

12
推荐指数
1
解决办法
5602
查看次数

iso8601使用swift4解码日期json

所以,我的json中有iso8601日期,看起来像"2016-06-07T17:20:00.000 + 02:00"

有没有办法使用swift4解析这些iso8601日期?我错过了一些明显的东西吗

我尝试了以下,但只有来自jsonShipA的dateString"2016-06-07T17:20:00Z"是可解析的....

import Foundation

struct Spaceship : Codable {
    var name: String
    var createdAt: Date
}

let jsonShipA = """
{
    "name": "Skyhopper",
    "createdAt": "2016-06-07T17:20:00Z"
}
"""

let jsonShipB = """
{
    "name": "Skyhopper",
    "createdAt": "2016-06-07T17:20:00.000+02:00"
}
"""

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

let dataA = jsonShipA.data(using: .utf8)!
if let decodedShip = try? decoder.decode(Spaceship.self, from: dataA) {
    print("jsonShipA date = \(decodedShip.createdAt)")
} else {
    print("Failed to decode iso8601 date format from jsonShipA")
}

let dataB …
Run Code Online (Sandbox Code Playgroud)

swift swift4

12
推荐指数
2
解决办法
7575
查看次数