迁移到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,...文件)?
谢谢!
我使用以下代码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),我获取该声明两条线以下的错误start和end:
'init' is unavailable
'init' was obsoleted in Swift 4.0
Run Code Online (Sandbox Code Playgroud)
我很困惑,因为我没有使用init.
我怎样才能解决这个问题?
我正在寻找一种方法,在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 …
我有以下代码:
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 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工作所必需的).
编辑:
我不确定它是否不会触发,因为它根本不起作用或者是由于我尝试归档的原因.总的来说,我希望通过推动硬件音量摇杆来获得有关音量变化的通知.
我是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) 我有和应用程序有一个单一的存储整个应用程序的信息.但是,当使用来自不同线程的单例时,这会产生一些数据争用问题.
这里有一个非常虚拟和简单化的问题版本:
独生子
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单例模型的重复,因为(如果我理解正确的话)那里他们正在解决访问单例对象本身的问题,但不能确保其属性的读写完成线程安全.
我有以下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
有三种方法可以摆脱编译器错误,但没有一种方法是好的:
实现一个init(from decoder: Decoder)只调用的空方法super.init().这似乎阻止了合成,意味着没有任何实际解码,因为它只是一个空方法.
init(from decoder: Decoder)手动实现整个方法.这有效,但现在使用的乐趣Codable几乎消失了.
删除所有与Realm相关的代码.现在Codable按预期工作,但是,现在我不能再使用Realm了.
这对我来说似乎是一个Swift错误,因为它应该检测到init(from decoder: Decoder)实际上是在实现,而不是手动执行.
我不知道的任何建议或解决方法?
我有一个UITableView,我将其标题设置为搜索栏.
tableView.tableHeaderView = searchController.searchBar
Run Code Online (Sandbox Code Playgroud)
一切都按计划工作,直到你点击它,它似乎脱离tableView并跳转到屏幕的顶部.tableView行保持不变.有什么理由在iOS 11而不是iOS 10中这样做吗?
所以,我的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)