I wrote a simple Network Extension for iOS:
class CFilterDataProvider: NEFilterDataProvider {
override func startFilter(completionHandler: #escaping (Error?) -> Void) {
NSLog("startFilter...")
// Add code to initialize the filter.
completionHandler(nil)
}
override func stopFilter(with reason: NEProviderStopReason, completionHandler: #escaping () -> Void) {
// Add code to clean up filter resources.
NSLog("stopFilter")
completionHandler()
}
override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict {
// Add code to determine if the flow should be dropped or not, downloading new rules if required.
return .drop()
}
}
After attaching to a process with Xcode, startFilter does not called in any situation.
My logs also indicate that function called successfuly but no action after attaching.
What's the reason for that?
Related
I have a protocol/function in my class which is below,
func getMovieList(completionHandler: #escaping (Result<[String], Error>) -> Void) { }
When the above method is called, I want to store the completion handler and call the success/error in the latter part.
I tried creating a typealias like below,
typealias AlbumListCompletionHandler = (((Result<[String], Error>)) -> Void)?
And in my class,
var completionHandlerObj: AlbumListCompletionHandler
func getMovieList(completionHandler: #escaping (Result<[String], Error>) -> Void) {
completionHandlerObj = completionHandler
/...
.../
}
But I wonder how do I call the success/error blocks in completionHandlerObj, kind of struck here. Can anyone help me with this ?
It should work like this
completionHandlerObj(.success(["",""]))
completionHandlerObj(.failure(ErrorObject))
i'm trying to implement simple didReceiveTrust in XMPPStreamDelegate, but Xcode shows warning on method definition:
func xmppStream(_ sender: XMPPStream!, didReceiveTrust trust: SecTrust, completionHandler: XMPPStreamCompletionHandler) {
completionHandler(true)
}
warning is following:
Instance method
'xmppStream(sender:didReceiveTrust:completionHandler:)' nearly matches
optional requirement 'xmppStream(_:didReceive:completionHandler:)' of
protocol 'XMPPStreamDelegate'
when testing app i'm getting following in output:
2018-06-12 23:10:11:239 MyMessages[55145:3561831] XMPPStream: Stream
secured with (GCDAsyncSocketManuallyEvaluateTrust == YES), but there
are no delegates that implement
xmppStream:didReceiveTrust:completionHandler:. This is likely a
mistake.
please help
following function definition works as expected:
func xmppStream(_ sender: XMPPStream?, didReceive trust: SecTrust?, completionHandler: #escaping (_ shouldTrustPeer: Bool) -> Void) {
completionHandler(true)
}
ReactiveSwift has this great function called flatMapError that allows you to respond with an event stream when an error occurs. A simple example might look like:
authenticationProducer.flatMapError { _ in self.reauthenticate() }
Whenever an error occurs, that error gets mapped into a producer that attempts to re-authenticate.
How would I build a similar operator using PromiseKit? The function signature would look like:
func flatMapError<U>(_ transform: #escaping (Error) -> Promise<U>) -> Promise<U>
My implementation so far:
func flatMapError<U>(_ transform: #escaping (Error) -> Promise<U>) -> Promise<U> {
return Promise<U> { resolve, reject in
self.catch { error in
let promise = transform(error)
let _ = promise.then { value in
resolve(value)
}
}
}
}
Use recover, it behaves as you request.
https://github.com/mxcl/PromiseKit/blob/master/Sources/Promise.swift#L254-L278
I am trying to get user data from a server. The application does not have to show any views until the data is loaded.
I read about typealias and I don't understand how to use it.
What I want: when data is loaded, move on to next step. If failed, load data again.
Here's how I declare typealias
typealias onCompleted = () -> ()
typealias onFailed = () -> ()
Here is my request code
func getUserData(_ completed: #escaping onCompleted, failed: #escaping onFailed){
let fullURL = AFUtils.getFullURL(AUTHURL.getUserData)
AFNetworking.requestGETURL(fullURL, params: nil, success: {
(JSONResponse) -> Void in
if let status = JSONResponse["status"].string {
switch status{
case Status.ok:
completed()
break
default:
failed()
break
}
}
})
}
But how could I use this on my view controller when calling getUserData?
Assuming your custom AFNetworking.requestGETURLs completion handler is called on the main queue:
func viewDidLoad() {
super.viewDidLoad()
getUserData({
//do somthing and update ui
}) {
//handle error
}
}
Edit:
How I understand your comment, you actually want to name your completion and error block parameters. If so, change the method to :
func getUserData(completion completed: #escaping onCompleted, error failed: #escaping onFailed){ ... }
and call it like this:
getUserData(completion: {
//do somthing and update ui
}, error: {
//handle error
})
My app is heavily dependent on the data that is coming. I want it to run the activity indicator and disable user interaction on the view while the data is being downloaded.
Is there a way to check or return something when the completion handler is done?
typealias CompletionHandler = (success:Bool) -> Void
func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {
**download code**
let flag = true
true if download succeed,false otherwise
completionHandler(success: flag)
}
How to use it.
downloadFileFromURL(NSURL(string: "url_str")!, { (success) -> Void in
**When download completes,control flow goes here.**
if success {
} else {
}
})
Define a property, which keeps completion handler, and call it when all the data is obtained:
var didObtainAllData: (() -> Void)?
func obtainData() {
....
// When data is obtained.
didObtainAllData?()
}
You can write
func processingTask(condition: String, completionHandler:(finished: Bool)-> Void) ->Void {
}
Use
processingTask("test") { (finished) in
if finished {
// To do task you want
}
}