How to cancel all requests in Alamofire's shared manager - alamofire

How to cancel all requests in Alamofire's shared manager?
This is my function:
class func cancelAllRequests() {
Alamofire.Manager.sharedInstance.session.getTasksWithCompletionHandler { (dataTasks, uploadTasks, downloadTasks) in
self.each(dataTasks, function: self.cancel)
self.each(uploadTasks, function: self.cancel)
self.each(downloadTasks, function: self.cancel)
}
}
class func cancel(index: Int, element: AnyObject) {
if let task = element as? NSURLSessionTask {
task.cancel()
}
}
class func each<T>(array: [T], function: (Int, T) -> ()) {
for (index, t) in enumerate(array) {
function(index, array[index])
}
}
Can it works?

Use NSURLSession's invalidateAndCancel method:
manager.session.invalidateAndCancel

This is for Swift 4.0 and Alamofire Version 4.5
Alamofire.SessionManager.default.session.getAllTasks{ $0.forEach{ $0.cancel() } }

For Alamofire version 5.0+, SessionManager has been replaced by Session. Just use
Session.default.cancelAllRequests()
to cancel all currently running requests created by AF.request().

Related

Mockito: How to mock lambda callback? what is the type? (Kotlin)

I have two class TestTarget, MockTarget and test code below. If the TestTarget has two functions with same name and same count of parameter, the any() is ambiguous. I need to assign the type to any(ClassType). But what is the type of () -> Unit? I have tried Function0 and it doesn't work. Can anyone help?
Class TestTarget:
Class TestTarget(private val mockTarget: MockTarget) {
fun testFunction() {
// some logic to be tested.
// call mockTarget.doSomething.
}
}
Class MockTarget
Class MockTarget {
fun doSomething(callback: () -> Unit) {
// some logic here.
}
fun doSomething(listener: OtherType) {
// Test code works without this function.
}
}
Test Code:
// setup mocks.
#Test
fun `verify testFunction`() {
`when`(mockTarget.doSomething(any())).thenAnswer { invocation ->
// callback here.
}
}
Replace org.mockito.Mockito with org.mockito.kotlin.*
and you can code like this
val anyLambda = any<() -> Unit>()
val anyListener = any<OtherType>()

Kotlin multiplatform: JobCancellationException: Parent job is Completed

I try to write a kotlin multiplatform library (android and ios) that uses ktor. Thereby I experience some issues with kotlins coroutines:
When writing tests I always get kotlinx.coroutines.JobCancellationException: Parent job is Completed; job=JobImpl{Completed}#... exception.
I use ktors mock engine for my tests:
client = HttpClient(MockEngine)
{
engine
{
addHandler
{ request ->
// Create response object
}
}
}
A sample method (commonMain module) using ktor. All methods in my library are written in a similar way. The exception occures if client.get is called.
suspend fun getData(): Either<Exception, String> = coroutineScope
{
// Exception occurs in this line:
val response: HttpResponse = client.get { url("https://www.google.com") }
return if (response.status == HttpStatusCode.OK)
{
(response.readText() as T).right()
}
else
{
Exception("Error").left()
}
}
A sample unit test (commonTest module) for the above method. The assertTrue statement is never called since the exception is thrown before.
#Test
fun getDataTest() = runTest
{
val result = getData()
assertTrue(result.isRight())
}
Actual implementation of runTest in androidTest and iosTest modules.
actual fun<T> runTest(block: suspend () -> T) { runBlocking { block() } }
I thought when I use coroutineScope, it waits until all child coroutines are done. What am I doing wrong and how can I fix this exception?
you can't cache HttpClient of CIO in client variable and reuse, It would be best if change the following code in your implementation.
val client:HttpClient get() = HttpClient(MockEngine) {
engine {
addHandler { request ->
// Create response object
}
}
}
The library must be updated, this glitch is in the fix report here: https://newreleases.io/project/github/ktorio/ktor/release/1.6.1
The problem is that you cannot use the same instance of the HttpClient. My ej:
HttpClient(CIO) {
install(JsonFeature) {
serializer = GsonSerializer()
}
}.use { client ->
return#use client.request("URL") {
method = HttpMethod.Get
}
}

WebRTC: How to pass RTCVideoEncoderSettings into RTCVideoEncoder

I am working on a webrtc screensharing app. Therefore I am utilizing the objective-c webrtc framework.
Now I have problems on how to pass in the RTCVideoEncoderSettings (http://cocoadocs.org/docsets/GoogleWebRTC/1.1.20266/Classes/RTCVideoEncoderSettings.html)
into an encoder (VP9). This is what I currently have:
public class CustomVideoEncoderFactory : NSObject, RTCVideoEncoderFactory {
var encoder: RTCVideoEncoder?
var preferredCodec: RTCVideoCodecInfo = RTCVideoCodecInfo(name: "VP9")
public func createEncoder(_ info: RTCVideoCodecInfo) -> RTCVideoEncoder? {
let vp9Encoder = RTCVideoEncoderVP9.vp9Encoder()!
// How to pass the RTCVideoEncoderSettings into this encoder???
return vp9Encoder
}
public func supportedCodecs() -> [RTCVideoCodecInfo] {
return [RTCVideoCodecInfo(name: "VP9")]
}
}
There is a method called startEncodeWithSettings (http://cocoadocs.org/docsets/GoogleWebRTC/1.1.20266/Protocols/RTCVideoEncoder.html)
but I am unsure how to integrate this with my current code. I tried to subclass (public class CustomVideoEncoder: NSObject, RTCVideoEncoder { ... }) which did not work.
Thank you for your help!
Ok, I found a solution. It turns out that for VP9 and VP8 there are the objective-c wrappings missing. VP9 and Vp8 are directly link to the native implementation!
Therefore it is ONLY possible to subclass if you are using h264.
For changing the settings on VP9 and VP8 it is necessary to modify the settings inside the c++ code!
Example of a custom Encoder Factory:
public class CustomVideoEncoderFactory : NSObject, RTCVideoEncoderFactory {
public func createEncoder(_ info: RTCVideoCodecInfo) -> RTCVideoEncoder? {
let encoder = super.createEncoder(info) // will create the h264 encoder
let customEncoder = CustomVideoEncoder()
self.encoder = customEncoder
return encoder
}
public func supportedCodecs() -> [RTCVideoCodecInfo] {
return [RTCVideoCodecInfo(name: kRTCVideoCodecH264Name)] }}
Example of a custom Encoder:
public class CustomVideoEncoder: NSObject, RTCVideoEncoder {
public var encoder: RTCVideoEncoder? // ONLY WORKS WITH h264
public func setCallback(_ callback: #escaping RTCVideoEncoderCallback) {
return encoder!.setCallback(callback)
}
public func startEncode(with settings: RTCVideoEncoderSettings, numberOfCores: Int32) -> Int {
// Change settings here !
let res = encoder!.startEncode(with: settings, numberOfCores: numberOfCores)
}
public func release() -> Int {
return encoder!.release()
}
public func encode(_ frame: RTCVideoFrame, codecSpecificInfo info: RTCCodecSpecificInfo?, frameTypes: [NSNumber]) -> Int {
return encoder!.encode(frame, codecSpecificInfo: info, frameTypes: frameTypes)
}
public func setBitrate(_ bitrateKbit: UInt32, framerate: UInt32) -> Int32 {
return encoder!.setBitrate(bitrateKbit, framerate: framerate)
}
public func implementationName() -> String {
return encoder!.implementationName()
}
public func scalingSettings() -> RTCVideoEncoderQpThresholds? {
return encoder!.scalingSettings()
}}
startEncodeWithSettings is an instance method, so you use it with an instance of it's type - did you try [encoder startEncodeWithSettings:param1 numberOfCores:param2]?

Cannot Import Protocol from Sinch Framework - SinRegionInfo

I have a project that I have built where I am trying to include the sinch framework for making SMS verification. I added Sinch to the project VIA cocoapods, and also by manually adding the folder/framework to my xcode file system.
The problem i'm having right now is that my version of the CountrySelectionViewController.swift cannot access the SinRegionInfo protocol defined inside of the Sinch framework... i'm not sure what is going wrong. An example of the code/error inside CountrySelectionViewController.swift is here:
var entries: Array<SINRegionInfo> = []; ---> Use of undeclared type 'SinRegionInfo'
The strange part is that everything seems to be the same in my project as it is in the sample project, but in the sample project, there is no problem accessing the protocol.
CountrySelectionViewController.swift
import UIKit
import SinchVerification
class CountrySelectionViewController : UITableViewController {
var isoCountryCode: String?
var onCompletion: ((String) -> Void)?
var entries: Array<SINRegionInfo> = [];
override func viewDidLoad() {
super.viewDidLoad();
let regionList = PhoneNumberUtil().regionList(forLocale: Locale.current);
entries = regionList.entries.sorted(by: { (a: SINRegionInfo, b: SINRegionInfo) -> Bool in
return a.countryDisplayName < b.countryDisplayName;
})
}
override func viewWillAppear(_ animated: Bool) {
let row = entries.index { (region: SINRegionInfo) -> Bool in
return region.isoCountryCode == isoCountryCode;
}
if row != nil {
tableView.selectRow(at: IndexPath.init(row: Int(row!), section: 0), animated: animated, scrollPosition: .middle);
}
}

May I implement one function of protocol in subclass?

I just modified it. Another problem is that if I want to have a subclass inherit from BaseParticipant, may I re-implement func performEvent inside the subclass?
For example:
class CyclingParticipant: BaseParticipant, Participant
{
init(name: String)
{
super.init(name: name, preferredEvent: Event.CYCLING)
}
func performEvent(event: Event, distance: Distance) throws
{
}
}
but the compiler said "redundant conformance of CyclingParticipant to protocol Participant .
class BaseParticipant: Participant
{
var name: String
var preferredEvent: Event
var raceTime: Int
var couldNotFinish: Bool
//var performedEvent: Event
// in swift, the class accepts protocol must impletment all funcs inside protocol
init(name: String, preferredEvent: Event)
{
self.name = name
self.preferredEvent = preferredEvent
self.raceTime = 0
self.couldNotFinish = false
}
func getName() -> String
{
return self.name
}
func getPreferredEvent() -> Event
{
return self.preferredEvent
}
func isDisqualified() -> Bool
{
return self.couldNotFinish
}
func addTime(addtionalRaceTime:Int) -> Void
{
self.raceTime += addtionalRaceTime
}
func setCouldNotFinish() -> Void
{
self.couldNotFinish = true
}
func performEvent(event: Event, distance: Distance) throws -> Int
{
return 1
}
func getTime() throws
{
}
}
The code of protocol Participant:
protocol Participant
{
func getName() -> String
func getPreferredEvent() -> Event
func isDisqualified() -> Bool
func performEvent(event: Event,distance: Distance) throws ->Int
func addTime(addtionalRaceTime: Int)
func setCouldNotFinish()
func getTime() throws
}
You're missing an implementation of the getTime() function as listed in your Protocol. Also, you should post such questions on Piazza. :P
[Updating to answer reworded question]
The BaseParticipant class already adopts the Participant protocol, so the CyclingParticipant subclass should not declare that it adopts it also, this is causing the redundant conformance error. Because BaseParticipant is already a Participant, any subclass of BaseParticipant will also be a Participant.
Change:
class CyclingParticipant: BaseParticipant, Participant
to:
class CyclingParticipant: BaseParticipant
All declared methods in a Swift protocol are required by default.
getTime() is not implemented