1

When I download an image from an URL it take around 6 seconds (even if the image isn't hd) and got an error in the log.

Here is my code for download the Image:

let backgroundQueue = DispatchQueue(label: "my.bk.job", qos: .background, target: nil)
    
backgroundQueue.async {
    let url = URL(string: "https://url/img.jpg")
    let data = try? Data(contentsOf: url!)
    //Show the image
}

And here is the Log error that I get:

2016-12-18 16:16:17.243477 yolo[1111:33384] [] nw_host_stats_add_src recv too small, received 24, expected 28
2016-12-18 16:16:17.247960 yolo[1111:33384] [] __nwlog_err_simulate_crash simulate crash already simulated "nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed: [42] Protocol not available"
2016-12-18 16:16:17.248434 yolo[1111:33384] [] nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed: [42] Protocol not available, dumping backtrace:
        [x86_64] libnetcore-856.30.16
    0   libsystem_network.dylib             0x000000010c1b7666 __nw_create_backtrace_string + 123
    1   libnetwork.dylib                    0x000000010c495006 nw_socket_add_input_handler + 3164
    2   libnetwork.dylib                    0x000000010c472555 nw_endpoint_flow_attach_protocols + 3768
    3   libnetwork.dylib                    0x000000010c471572 nw_endpoint_flow_setup_socket + 563
    4   libnetwork.dylib                    0x000000010c470298 -[NWConcrete_nw_endpoint_flow startWithHandler:] + 2612
    5   libnetwork.dylib                    0x000000010c48bae1 nw_endpoint_handler_path_change + 1261
    6   libnetwork.dylib                    0x000000010c48b510 nw_endpoint_handler_start + 570
    7   libnetwork.dylib                    0x000000010c4a31f9 nw_endpoint_resolver_start_next_child + 2240
    8   libdispatch.dylib                   0x000000010bf34978 _dispatch_call_block_and_release + 12
    9   libdispatch.dylib                   0x000000010bf5e0cd _dispatch_client_callout + 8
    10  libdispatch.dylib                   0x000000010bf3be17 _dispatch_queue_serial_drain + 236
    11  libdispatch.dylib                   0x000000010bf3cb4b _dispatch_queue_invoke + 1073
    12  libdispatch.dylib                   0x000000010bf3f385 _dispatch_root_queue_drain + 720
    13  libdispatch.dylib                   0x000000010bf3f059 _dispatch_worker_thread3 + 123
    14  libsystem_pthread.dylib             0x000000010c3074de _pthread_wqthread + 1129
    15  libsystem_pthread.dylib             0x000000010c305341 start_wqthread + 13

The code work because I can see the Image but is slow and this error don't seem good to me, What I'm doing wrong? (I'm using Swift 3)

EDIT:

I tried the code in a white new project with literally nothing in and still receive it.

I copy/pasted this code too but got the same error.

I changed URL and now the download time is correct so I'll keep this error and I'll use this code.

Thank you all for the help I upvoted all the useful answer

Rob
  • 415,655
  • 72
  • 787
  • 1,044
GMX
  • 950
  • 1
  • 14
  • 29

3 Answers3

3

You must do UI stuff on the main queue:

backgroundQueue.async {
    let url = URL(string: "https://url/img.jpg")
    let data = try? Data(contentsOf: url!)
    DispatchQueue.main.async {
        //Show the image
    }
}
shallowThought
  • 19,212
  • 9
  • 65
  • 112
  • I got: Module 'Dispatch' has no member named 'queue' – GMX Dec 18 '16 at 15:40
  • Sorry. Updated answer. – shallowThought Dec 18 '16 at 15:41
  • Now I can run your code but got the same error in the log, nothing change – GMX Dec 18 '16 at 15:48
  • ShallowThought's answer is correct. You absolutely **must** do UI code on the main thread. The code at the "//show the image" line needs to be wrapped in a call to the main thread. The `DispatchQueue.main.async()` GCD call is the normal way to do this in Swift. You could also use the older `performSelector(onMainThread)` function, but I don't recommend that. Selectors are not very "Swifty" – Duncan C Dec 18 '16 at 16:07
2

These useless of logs always display on XCode 8. Set an Environment Variables OS_ACTIVITY_MODE = Disable on XCode Edit Scheme -> Arguments to add if you don't want to see them.

Principles:

1.Download any file or image through sub thread with async 2.After downloaded, update image to UI through main thread with sync

That's easy to solve that.

Johnny
  • 1,112
  • 1
  • 13
  • 21
0

The errors/warnings may not be related to your code.

See here for the SO_NOAPNFALLBK message and here for the rest.

Community
  • 1
  • 1
Bogdan Farca
  • 3,856
  • 26
  • 38
  • If I delete the backgroundQueue.async (so the Image download) all work good without any error... – GMX Dec 18 '16 at 15:47
  • Except then you are doing your download synchronously on the main thread, which is a bad idea. It will cause your UI to freeze while the download completes. Worse, If the download times out your app could be terminated for being unresponsive. – Duncan C Dec 18 '16 at 16:09