Post not yet marked as solved
I'm trying to make an example to show using the thread sanitizer and so I used this code.final class MainViewController: UIViewController {
var counter = 0
override func viewDidLoad() {
super.viewDidLoad()
let queue = DispatchQueue(label: "q", qos: .background)
queue.async {
for _ in 1 ... 10000 {
self.counter += 1
}
}
DispatchQueue.main.async {
for _ in 1 ... 10000 {
self.counter += 1
}
}
}
}It doesn't have any issues with it. However, if I change the counter variable like so: var counter = 0 {
didSet {
print(#line, counter)
}
}And then run it, then it aborts. It's also critical for the #line there. Without, it doesn't fail. I'm completely confused on why the print with the line number triggers the read/write across threads but without it thread sanitizer has no issues.
Post not yet marked as solved
In my UITableViewCell subclass I have a UITextView and a UIImageView. The image covers the upper left corner of the UITextView and so I want to set an exclusion path so that the text wraps around the image. I'm doing it like this:override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let choiceCell = cell as! ItemChoiceTableViewCell
guard choiceCell.textView.textContainer.exclusionPaths.count == 0 else { return }
var frame = choiceCell.displayImageView.bounds
frame.size.height -= choiceCell.textView.frame.origin.y - choiceCell.displayImageView.frame.origin.y
choiceCell.textView.textContainer.exclusionPaths = [UIBezierPath(rect: frame)]
choiceCell.layoutSubviews()
}The height of the cell is usually a line too short though, and I believe what is happening is that the necessary size isn't being properly recalculated after the exclusion path is added in. I've tried various things in place of layoutSubviews like setNeedsLayout and setNeedsDisplay but I can't get any of them to work properly.How do I force the size of the UITextView to recalculate after the exclusion path is added?
Post not yet marked as solved
I'm trying to get JSON output like so:{ "day" : "2019-01-01", "bob" : 73, "frank" : 34.3}So basically my value can be either a string or a number. I can represent that in Swift via `[String: Any]` of course, but that won't pass through a JSONEncoder. Other than making all my numbers strings...how do I handle that?
Post not yet marked as solved
I'm using multiple targets in my project and so I've created an App Group to allow both targets to read/write from Core Data. The saves happen in the second target, and if I restart the app my table display the newly saved item. What I can't figure out though is when the other target saves a new entity, how do the NSFetchedResultsController in the primary target know to refresh the table? I've tried catching things from NotificationCenter but those don't seem to cross targets.
Post not yet marked as solved
Does anyone know why the apns-collapse-id key is sent as an HTTP/2 header, instead of being part of the `aps` payload?
Post not yet marked as solved
How can I tell JSONEncoder that it SHOULD include they property key even when the optional value is nil? In the generated JSON I want a null. For example:struct Foo : Codable {
var id = 7
var foo: String?
}
let data = try! JSONEncoder().encode(Foo())
String(data: data, encoding: .utf8)That just prints out{"id":7}when what I really want is:{"id":7,"foo":null}
Post not yet marked as solved
I've got an item of type WritableKeyPath<T, Double?> and then I'm trying to use that keypath in Decoder's decode method, but that wants something of type KeyedDecodingContainer.KeyIs there a way to get from the former to the latter?
Post not yet marked as solved
In my custom UI for a push notification I have three buttons, one of which is a UNTextInputNotificationAction, which pops up the keyboard. In the didReceive(_:completionHandler:) method I'm calling the completionHandler with .doNotDismiss because they might push more than one button or make a comment. However, if the first thing they click is the button for the keyboard, and then I hit Send, the keyboard still stays on the screen.How do I make the keyboard go away so the action buttons are visible again but not dismiss the entire notification?
Post not yet marked as solved
I'm using libcurl on my server side PHP script to send PHP notifications via HTTP/2. In my headers I'm sending an ID, like so:curl_setopt($ch, CURLOPT_HTTPHEADER, [
'apns-topic: ' . BUNDLE_ID,
'Authorization: Bearer ' . generateAuthenticationHeader(),
'apns-collapse-id', 'qwer1235'
]);When the notification comes in I don't acknowledge it on the phone, and then I send another message with a different alert title. Both messages are then displayed on the phone. My understanding of the apns-collapse-id is that it should have removed the older message and replaced it with this new one.Am I missing something?
Post not yet marked as solved
So I'm still working on my HTTP/2 implementation. I know, I'm crazy. I'm opening an InputStream and OutputStream to the apns site but I'm getting a CFNetwork SSLHandshake failure. I'm not sure where to even start looking for how to handle this. I've opened my connection like so: Stream.getStreamsToHost(withName: host, port: port, inputStream: &inputStream, outputStream: &outputStream)
super.init()
inputStream!.delegate = self
inputStream!.setProperty(StreamSocketSecurityLevel.tlSv1.rawValue, forKey: .socketSecurityLevelKey)
inputStream!.schedule(in: .main, forMode: .defaultRunLoopMode)
inputStream!.open()
outputStream!.delegate = self
outputStream!.setProperty(StreamSocketSecurityLevel.tlSv1.rawValue, forKey: .socketSecurityLevelKey)
outputStream!.schedule(in: .main, forMode: .defaultRunLoopMode)
outputStream!.open()And then I write the "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" message to the outputStream. I'm using api.development.push.apple.com as the host and 443 as the port.After a few seconds I get back this:MessageTracer: load_domain_whitelist_search_tree:73: Search tree file's format version number (0) is not supportedMessageTracer: Falling back to default whitelistCFNetwork SSLHandshake failed (-9806)TCP Conn 0x60c000160a80 SSLHandshake failed (-9806)SocketStream write error [0x60c000160a80]: 3 -9806
When that function is called, will eventCode ever be more than one item? The documentation isn't really clear on this. eventCode is an OptionSet, not an enum, so in theory multiple items could exist at the same time, right?
Post not yet marked as solved
For my public init method I'm using a Sequence type so that I can support multiple "things" coming in. Internally I want an array of UInt8 but this way I can let them pass a Data object, for example, so I've defined my primary initializer to take the sequence of bytes. A common case though will be to pass in a string value so I'm trying to make a convenience initializer. class Example {
public init<Bytes : Sequence>(padding: Bytes? = nil, data: Bytes? = nil) throws where Bytes.Element == UInt8 {
}
convenience init<Bytes : Sequence>(padding: Bytes?, stringData: String) throws where Bytes.Element == UInt8 {
let encodedData = [UInt8](stringData.utf8)
try self.init(padding: padding, data: encodedData)
}
}Line 7, above, is giving a compiler error: Cannot convert value of type '[UInt8]' to expected argument type '_?'I don't understand why it's getting that error as it can see it's an array of UInt8, which is what the designated initializer wants to receive.
I have a base type and subtypes, like shown below.class Base {
init() throws {
}
}
class Foo : Base {
override init(data: [UInt8]) throws { }
}
class Bar : Base {
override init(data: [UInt8]) throws { }
}And now in my code elsewhere I want to "point" to the initializer. So basically I wanna do something like this illegal code:func foo(data: [UInt8]) {
let ptr = ((data: [UInt8]) -> Base) = conditional ? Foo : Bar
let item = ptr(data: data)
}
I'm trying to get a simple index offset:func foo<Bytes: Collection>(data: Bytes) where Bytes.Element == UInt8 {
let nextFrameStartIndex = data.index(data.startIndex, offsetBy: 10, limitedBy: data.endIndex)
}If I put the integer literal 10 there it compiles just fine. If I instead create a variable of type Int and pass that I get a compiler error:"Cannot invoke 'index' with an argument list of type '(Bytes.Index, offsetBy: Int, limitedBy: Bytes.index)'
Post not yet marked as solved
Is there a simple way to unit test that I'll get a specific error thrown? I currently stuck writing this ugliness. func testEncodedDataFrameMustHaveStream() {
do {
_ = try DataFrame(stream: Http2Stream.connectionStream)
} catch Http2Error.protocolError {
// Good!
} catch {
XCTFail("Should have thrown a protocol error")
}
}There apparently used to be something like XCTAssertThrowsSpecific but I'm not finding that any longer.