unused_import: false rule violation (importing SwiftUI to use ObservableObject and @Published in a macOS project)
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 19.7k
- Forks
- 2.3k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 11
Description
New Issue Checklist
- Updated SwiftLint to the latest version
- I searched for existing GitHub issues
Describe the bug
Multi-target (iOS and macOS) project, when building for macOS (platform is important for my example: the code is a replacement for the EditMode SwiftUI provides on iOS but not on macOS), I have a file that imports SwiftUI to be able to specify that a class conforms to the ObservableObject protocol, and has a @Published property.
The unused_import rule is incorrectly reporting that import call as unused. If I remove the import line, I get errors in Xcode:
Cannot find type 'ObservableObject' in scopeUnknown attribute 'Published'
So, clearly, the compiler uses the import.
Complete output when running SwiftLint, including the stack trace and command used
Xcode Build:
$ xcodebuild -project WebExtractor.xcodeproj -scheme WebExtractor -destination platform=macOS,arch=x86_64 > xcodebuild.log
Outputs:
2023-08-10 20:06:15.685 xcodebuild[73360:7531983] DVTCoreDeviceEnabledState: DVTCoreDeviceEnabledState_Disabled set via user default (DVTEnableCoreDevice=disabled)
The SwiftLint Analyse:
$ swiftlint analyze --compiler-log-path xcodebuild.log
Outputs:
Analyzing Swift files in current working directory
... (many Collecting lines omitted) ...
... (many Analyzing lines omitted) ...
Analyzing 'EditMode.swift' (9/14)
/Users/user/Projects/MyApp/MyApp/Views/EditMode.swift:1:1: warning: Unused Import Violation: All imported modules should be required to make the file compile (unused_import)
... (more Analyzing lines omitted) ...
Done analyzing! Found 1 violation, 0 serious in 41 files.
Environment
- SwiftLint version 0.52.4
- Installation method used: Homebrew
- Paste your configuration file:
# Here’s the whole thing, even though just the analyzer_rules: unused_import matters for this report
disabled_rules:
- for_where
- force_cast
opt_in_rules:
- accessibility_label_for_image
- accessibility_trait_for_button
- anonymous_argument_in_multiline_closure
- array_init
- attributes
- balanced_xctest_lifecycle
- closure_body_length
- closure_end_indentation
- closure_spacing
- collection_alignment
- comma_inheritance
- conditional_returns_on_newline
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_first_not_nil
- contains_over_range_nil_comparison
- convenience_type
- direct_return
- discarded_notification_center_observer
- discouraged_assert
- discouraged_none_name
- discouraged_object_literal
- discouraged_optional_boolean
- discouraged_optional_collection
- empty_collection_literal
- empty_count
- empty_string
- empty_xctest_method
- enum_case_associated_values_count
- expiring_todo
- explicit_init
- fallthrough
- fatal_error_message
- file_header
- file_name
- file_name_no_space
- file_types_order
- first_where
- flatmap_over_map_reduce
- function_default_parameter_at_end
- ibinspectable_in_extension
- identical_operands
- implicit_return
- implicitly_unwrapped_optional
- indentation_width
- joined_default_parameter
- last_where
- legacy_multiple
- legacy_objc_type
- legacy_random
- let_var_whitespace
- literal_expression_end_indentation
- local_doc_comment
- lower_acl_than_parent
- missing_docs
- modifier_order
- multiline_arguments
- multiline_arguments_brackets
- multiline_function_chains
- multiline_literal_brackets
- multiline_parameters
- multiline_parameters_brackets
- nimble_operator
- no_extension_access_modifier
- no_magic_numbers
- nslocalizedstring_key
- nslocalizedstring_require_bundle
- number_separator
- object_literal
- operator_usage_whitespace
- optional_enum_case_matching
- overridden_super_call
- override_in_extension
- pattern_matching_keywords
- period_spacing
- prefer_self_in_static_references
- prefer_self_type_over_type_of_self
- prefer_zero_over_explicit_init
- private_action
- private_subject
- prohibited_super_call
- quick_discouraged_call
- quick_discouraged_focused_test
- quick_discouraged_pending_test
- raw_value_for_camel_cased_codable_enum
- reduce_into
- redundant_nil_coalescing
- redundant_type_annotation
- required_enum_case
- return_value_from_void_function
- self_binding
- shorthand_optional_binding
- single_test_class
- sorted_enum_cases
- sorted_first_last
- sorted_imports
- static_operator
- strict_fileprivate
- strong_iboutlet
- superfluous_else
- switch_case_on_newline
- test_case_accessibility
- toggle_bool
- trailing_closure
- unavailable_function
- unhandled_throwing_task
- unneeded_parentheses_in_closure_argument
- unowned_variable_capture
- untyped_error_in_catch
- vertical_parameter_alignment_on_call
- vertical_whitespace_between_cases
- vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces
- weak_delegate
- xct_specific_matcher
- yoda_condition
analyzer_rules:
- capture_variable
- explicit_self
- typesafe_array_init
- unused_import
attributes:
always_on_same_line:
- "@Environment"
- "@IBAction"
- "@NSManaged"
identifier_name:
excluded:
- id
- to
type_name:
excluded:
- ID
- Xcode 14.3.1
- macOS 13.5 (Intel)
- Do you have a sample that shows the issue?
// EditMode.swift
import SwiftUI
final class EditMode: ObservableObject {
@Published var isEditing = false
}
(I normally have the content of that file wrapped in #if os(macOS) … #endif compiler directives, but trimmed that out and built just for the macOS destination to see if that would change anything, but the incorrect rule warning came out the same.)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the unused_import analyzer rule and reproduce the warning using EditMode.swift, the SwiftUI import, and the provided xcodebuild.log. Run swiftlint analyze --compiler-log-path xcodebuild.log for the macOS destination and compare the result with the compiler errors produced when the import is removed. Done means valid imports used only by ObservableObject and @Published are no longer reported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100