DispatchQueue.main.async Not Work when Using RunLoop In Swift Package

I'm writing a simple executableTarget in swift package to test RunLoop and DispatchQueue.

// main.swift
import Foundation

let rl = RunLoop.current
let timer = Timer(fire:Date(), interval: 1, repeats: true) { timer in
    print("loop start")
    DispatchQueue.main.async {
        print("never runs")
    print("loop end")
rl.add(timer, forMode: RunLoop.Mode.common)

The RunLoop works fine, but the DispatchQueue.main.async block Never runs.

Then I create another project of a macOS Command Line Tool with the same code above.
The DispatchQueue.main.async works.

I'm wondering why is that, and how to make the swift package's executableTarget works.

The swift package config is like this:

// Package.swift

// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Concurrency",
    platforms: [
    dependencies: [],
    targets: [
            name: "Concurrency",
            dependencies: []),
            name: "ConcurrencyTests",
            dependencies: ["Concurrency"]),


The documentation in the header file for dispatch_get_main_queue says:

The main queue is meant to be used in application context to interact with the main thread and the main runloop.

Because the main queue doesn't behave entirely like a regular serial queue, it may have unwanted side-effects when used in processes that are not UI apps (daemons). For such processes, the main queue should be avoided.

Could it be that you’re you’re experiencing one of these side effects when using SPM?

Terms of Service

Privacy Policy

Cookie Policy