AlamofireImage: How to set timeoutIntervalForRequest for af_setImage? - alamofire

I am trying to use af_setImage to add images to UICollectionViewCell. Default timeoutIntervalForRequest is 60 seconds, but I should not wait the user more than 15 seconds. How can I set the custom timeoutIntervalForRequest for af_setImage? I tried below solutions, but they did not work.
let downloader = UIImageView.af_sharedImageDownloader
let configuration = downloader.sessionManager.session.configuration
configuration.timeoutIntervalForResource = 15
configuration.timeoutIntervalForRequest = 15
af_setImage(withURL: url, completion: { (response) in
// do stuff
})
Tried bottom solution to but didn't work
af_imageDownloader?.sessionManager.session.configuration.timeoutIntervalForResource = 15
af_imageDownloader?.sessionManager.session.configuration.timeoutIntervalForRequest = 15
//tried this instead of af_setImage, this is not working too.
af_imageDownloader?.sessionManager.request(URLRequest(url: url))
.responseJSON {
response in
switch (response.result) {
case .success:
// success
break
case .failure(let error):
// fail
break
}
}

Related

Axios update value outside of then to break the loop

I'm still currently learning on using React Native.
What I'm trying to do is update the limit value to 1 so it would break the while loop, but I am not sure on how to execute it since I can't update the value from inside the .then() in Axios POST call.
Glad if anyone would point out any method to handle this. Thank you for your help.
var limit = 0;
while (limit == 0) {
running = running + 20;
console.log("restart");
postDataCalories = {
"query": `${running} minutes run and ${walking} minutes walking`,
"gender":"male",
// "nf_calories": 363.62,
"weight_kg":63.5,
"height_cm":167.64,
"age":30
};
console.log(`${running} minutes run and ${walking} minutes walking`);
axios.post('https://trackapi.nutritionix.com/v2/natural/exercise', postDataCalories, axiosConfig2)
.then((res3) => {
console.log("exercise RESPONSE RECEIVED: ", res3);
let caloriesFood = res2.data.foods[0].nf_calories;
let caloriesExercise = res3.data.exercises[0].nf_calories;
let caloriesDifferences = caloriesFood - caloriesExercise;
console.log("hi " + caloriesDifferences);
if (caloriesDifferences < 50){
console.log('done');
limit = 1;
} else {
console.log('nope');
}
})
}
That's right in your case you cannot break the while loop inside the then-function because that function is called at a different moment in time (they call it asynchronous).
There are two things you can do. If you have access to await/async in your environment you could rewrite it to:
async someFunction() {
var limit = 0;
var running = 1; // arbitrarily start at 1.
while (limit == 0) {
running = running + 20;
console.log("restart running " + running);
postDataCalories = {
"query": `${running} minutes run and ${walking} minutes walking`,
"gender":"male",
// "nf_calories": 363.62,
"weight_kg":63.5,
"height_cm":167.64,
"age":30
};
console.log(`${running} minutes run and ${walking} minutes walking`);
var res3 = await axios.post('https://trackapi.nutritionix.com/v2/natural/exercise', postDataCalories, axiosConfig2)
console.log("exercise RESPONSE RECEIVED: ", res3);
let caloriesFood = res2.data.foods[0].nf_calories;
let caloriesExercise = res3.data.exercises[0].nf_calories;
let caloriesDifferences = caloriesFood - caloriesExercise;
console.log("hi " + caloriesDifferences);
if (caloriesDifferences < 50){
console.log('done');
limit = 1;
// you may also do:
break;
} else {
console.log('nope');
}
}
}
}
For usual web conditions it requires either a modern browser (Firefox/Chrome) (or when you have babel / regenerator-runtime might do the trick, maybe your setup is already capable of transpiling this/running this.)
If you dont have access to async/await then you need to apply recursion (to work around the synchronicity). Normally you can perform the tasks sequentially (in a row, step by step, using a while loop), now you would write something like:
function runTheLoop(running, walking) {
postDataCalories = {
"query": `${running} minutes run and ${walking} minutes walking`,
"gender":"male",
// "nf_calories": 363.62,
"weight_kg":63.5,
"height_cm":167.64,
"age":30
};
console.log(`${running} minutes run and ${walking} minutes walking`);
axios.post('https://trackapi.nutritionix.com/v2/natural/exercise', postDataCalories, axiosConfig2)
.then((res3) => {
console.log("exercise RESPONSE RECEIVED: ", res3);
let caloriesFood = res2.data.foods[0].nf_calories;
let caloriesExercise = res3.data.exercises[0].nf_calories;
let caloriesDifferences = caloriesFood - caloriesExercise;
console.log("hi " + caloriesDifferences);
if (caloriesDifferences < 50){
console.log('done');
// limit = 1;
return;
} else {
console.log('nope');
// This is the recursive variant of "running the loop again"
return runTheLoop(running + 20, walking + 20);
}
})
}
}
// Somewhere:
console.log("restart");
// one minute of walking and one minute of running.
runTheLoop(1, 1);
Note: I've used your your code to make the examples relevant in to your situation, I could not test it out myself so it may not work directly if you copy and paste this.

Flutter: BLoC, testing streams

Testing the bloc pattern is not so clear to me. So, if I have these 2 stream controllers:
final _controller1 = StreamController();
final _controller2 = StreamController<bool>;
Sink get controller1Add = _controller1.sink;
Stream<bool> get controller2Out = _controller2.stream;
and I want to test that, from this function:
submit() {
if (_controller1.value == null ||
_controller1.value.isEmpty) {
print(...)
return;
}else
_controller2.sink.add(true);
}
the _controller2.stream should have true, how should I do?
I tried something like:
test("test", (){
bloc.submit();
expect(bloc.controller2Out, emitsAnyOf([true]));
});
but, of course, it didnĀ“t work.
I've modified your code to use the RxDart's BehaviorSubject and it seems to work. You are using StreamController but I get error cause it doesn't have the value property.
final _controller1 = BehaviorSubject<String>();
final _controller2 = BehaviorSubject<bool>();
Sink get controller1Add => _controller1.sink;
Stream<bool> get controller2Out => _controller2.stream;
submit() {
if (_controller1.value == null || _controller1.value.isEmpty) {
print('Error');
_controller2.sink.add(false);
return;
} else {
print('OK');
_controller2.sink.add(true);
}
}
The test:
bloc.controller1Add.add('');
bloc.submit();
expect(bloc.controller2Out, emits(false));
bloc.controller1Add.add('test');
bloc.submit();
expect(bloc.controller2Out, emits(true));
bloc.controller1Add.add('');
bloc.submit();
expect(bloc.controller2Out, emits(false));

Best practice to safely load image from url

I have the following code snippet to load an image from an url:
let url = NSURL(string: imageUrl)
let data = NSData(contentsOfURL: url!)
let image = UIImage(data: data!)
In case that my variable imageUrl has a valid string value, what is the most secure way to protect this code against possible edge cases?
Following code seems not to be very handy:
if let url = NSURL(string: imageUrl) {
if let data = NSData(contentsOfURL: url) {
if let image = UIImage(data: data) {
// success -> do something with the image...
}
else {
// print error message
}
}
else {
// print error message
}
}
else {
// print error message
}
The best practice is not to use a synchronous method like contentsOfURL to load data from over the network.
The recommended way is NSURLSession which works asynchronously.
This is a simple example with a completion block and an enum with associated types,
it catches all possible errors
enum Result {
case Success(UIImage), Failure(NSString)
}
func loadImage(string : String, completion: (Result) -> ()) {
guard let url = NSURL(string: string) else {
completion(.Failure("Bad URL"))
return
}
NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
if error != nil {
completion(.Failure(error!.localizedDescription))
} else {
guard let image = UIImage(data: data!) else {
completion(.Failure("Could not load image data"))
return
}
completion(.Success(image))
}
}.resume()
}
Call it with:
loadImage("http://myserver.com/path/to/image.png") { result in
switch result {
case .Success(let image) :
// do something with the image
case .Failure(let error) :
print(error)
}
}

CasperJS looking for 404 error on links site

I'm beginner programmer. I found nice script
http://planzero.org/blog/2013/03/07/spidering_the_web_with_casperjs
I tried to rewrite this script with CasperJS test framework.
I would to get xunit report from this code
var startUrl = 'http://yoursite.foo';
var visitedUrls = [], pendingUrls = [];
var casper = require('casper').create({
pageSettings: {
loadImages: false,
loadPlugins: false
}});
var utils = require('utils')
var helpers = require('helpers')
// Spider from the given URL
casper.test.begin('href' , function(test) {
casper.start(startUrl, function() {
function spider(url) {
// Add the URL to the visited stack
visitedUrls.push(url);
// Open the URL
casper.open(url).then(function() {
test.assertHttpStatus(200, ":" + url);
// Find links present on this page
var links = this.evaluate(function() {
var links = [];
Array.prototype.forEach.call(__utils__.findAll('a'), function(e) {
links.push(e.getAttribute('href'));
});
return links;
});
// Add newly found URLs to the stack
var baseUrl = this.getGlobal('location').origin;
Array.prototype.forEach.call(links, function(link) {
var newUrl = helpers.absoluteUri(baseUrl, link);
if (pendingUrls.indexOf(newUrl) == -1 && visitedUrls.indexOf(newUrl) == -1 && !(link.search(startUrl) == -1)) {
pendingUrls.push(newUrl);
}
});
// If there are URLs to be processed
if (pendingUrls.length > 0) {
var nextUrl = pendingUrls.shift();
spider(nextUrl);
}
else {
console.log('links ended');
this.break;
}
});
}
spider(startUrl);
}).run(function(){
test.done();
});
});
Script is running but when he and Job I can't get report.
If you're trying to learn how to use CasperJS you need to start with a smaller example than that. That script is a mess which goes after a site named yoursite.foo (maybe you put that name in there?)
I would take small steps. I have a video which may help explain how to use CasperJS.
http://www.youtube.com/watch?v=Kefil5tCL9o

phantomJS webpage timeout

I have set up a script to create webshots of our app.
It runs perfectly and all is fine Until I encounter an image with a broken url :
"<img src='http://testserver.our.intranet/fetch/image/373e8fd2339696e2feeb680b765d626e' />"
I have managed to break the script after 6 seconds using the below, Before it was just looping forever.
But, is it possible to ignore the network request (AKA take the image out of DOM) and then proceed to create the thumb without the image, (or with an injected image missing image !)
var page = require('webpage').create(),
system = require('system'),
address, output, size;
if (system.args.length < 3 || system.args.length > 5) {
phantom.exit(1);
} else {
address = system.args[1];
output = system.args[2];
page.viewportSize = { width: 640, height: 640 };
page.zoomFactor = 0.75;
page.clipRect = { top: 10, left: 0, width: 640, height: 490 };
try{
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 200);
}
});
} finally{
setTimeout(function() {
console.log("Max execution time " + Math.round(6000) + " seconds exceeded");
phantom.exit(1);
}, 6000);
}
}
PhantomJS 1.9 has introduced a new setting, resourceTimeout, that controls how long a request can take before it gets cancelled. Along with that, there's a onResourceTimeout event that is triggered if/when a request times out.
Here's a code snippet illustrating all of the above:
var page = require('webpage').create();
page.settings.resourceTimeout = 5000; // 5 seconds
page.onResourceTimeout = function(e) {
console.log(e.errorCode); // it'll probably be 408
console.log(e.errorString); // it'll probably be 'Network timeout on resource'
console.log(e.url); // the url whose request timed out
phantom.exit(1);
};
page.open('http://...', function (status) {
...
}
Unfortunately those options are poorly documented right now. I had to go through GitHub discussions and the PhantomJS source code in order to find them out.