Skip to content

Conversation

@OlivellaO
Copy link
Collaborator

@OlivellaO OlivellaO commented Oct 13, 2025

SpikeWPB-20878 [iOS] Periphery integration with Xcode

PROPOSAL

This PR adds a new target for Periphery tool to be run so we can get a report on Xcode (and as extra on a text file) of unused code that we can delete.

This is a short description of each file:

  • run-from-xcode.sh -> This is the script that will execute "periphery scan" command. It will check if Periphery v3 is install on the machine and if not install it using homebrew.
  • unused-code.txt -> File generated when running the script on Xcode. Created using "tee" terminal command
  • unused-code-parser.py -> Script in Phyton to create Markdown files from unused-code.txt. It will group the warnings by file and create a different file for each project.

This is a screenshot of the new target added to Wire-iOS project:
Captura de pantalla 2025-10-13 a las 11 22 19

Testing Periphery

  1. Checkout branch
  2. Open Xcode
  3. Select Periphery target and click "play" button
Captura de pantalla 2025-10-13 a las 11 23 44
  1. When build is done warning will show up on warnings tab.
Captura de pantalla 2025-10-13 a las 11 24 59

Testing Parsing script

There is no automatic execution of the parser. You can run it locally if you need to generate the reports.

  1. Open terminal
  2. Ideally go to periphery folder in Wire-iOS project folder (wire-ios/periphery)
  3. Execute script with ./unused-code-parser.py <path_to_log_file>
  4. Script will clean all previous Markdown files and parse the log file to create updated ones.
  5. After the script is finish you should see all reports on "wire-ios/periphery/reports"

Checklist

  • Title contains a reference JIRA issue number like [WPB-XXX].
  • Description is filled and free of optional paragraphs.
  • Adds/updates automated tests.

UI accessibility checklist

If your PR includes UI changes, please utilize this checklist:

  • Make sure you use the API for UI elements that support large fonts.
  • All colors are taken from WireDesign.ColorTheme or constructed using WireDesign.BaseColorPalette.
  • New UI elements have Accessibility strings for VoiceOver.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 13, 2025

Test Results

1 876 tests   1 849 ✅  2m 9s ⏱️
  299 suites     27 💤
    1 files        0 ❌

Results for commit be17823.

♻️ This comment has been updated with latest results.

@OlivellaO
Copy link
Collaborator Author

If you want to ask why Python for the script it just because its fast parsing big files. I've tried Kotlin at first but it makes things harder and it's slower.

@caldrian caldrian self-requested a review October 13, 2025 10:51

export PATH="$PATH:/opt/homebrew/bin"

echo "Ensuring Periphery v3+ is installed..."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question/suggestion: Wouldn't it be better to depend on periphery being installed instead of silently executing an installation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I had in mind that if at some point we want to automate this we will need to make sure that periphery is installed.

Copy link
Collaborator Author

@OlivellaO OlivellaO Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SyamalaHari suggested we could add Periphery as dependency on Wire-iOS using SPM as describe in this article: https://medium.com/@ashokatonline/periphery-the-code-optimization-tool-every-developer-needs-1e43ce81ac88
Maybe we could do that and remove the installation and version checks from the script, what do you think?

# To know what each param does check https://github.com/peripheryapp/periphery?tab=readme-ov-file#analysis
periphery scan \
--project wire-ios-mono.xcworkspace \
--schemes "Wire-iOS" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to build a few more schemes. Wire-iOS doesn't cover all code, if I'm not mistaken.

Copy link
Collaborator Author

@OlivellaO OlivellaO Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Periphery v3 with this configuration covers a lot of the code. Probably not all of it but i think as a first approach should be fine and we have something to start working on.

I was also concern that adding more schemes might report more "false positive" when scanning (the tool is not perfect), but it could be the oposite too.

I can test adding more schemes here and compare the output with the actual one. Do you have any suggestions about what schemes should we add to cover all the code?

@OlivellaO
Copy link
Collaborator Author

OlivellaO commented Oct 13, 2025

@WilhelmOks Noticed that run-from-xcode.sh is working on Xcode 16.4 but sometimes not on the last Xcode 26. I still don't know the reason.

Copy link
Contributor

@samwyndham samwyndham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I'm a bit torn about adding Periphery to the project.

I really like periphery as a tool but don't really know how to make best use of it. For example we currently see that it identifies about 6000 issues. But these contain quite a lot of false positives/negatives as far as I know. For example:

WireAuthentication/Sources/WireAuthentication/Components/RootComponent.swift:134:10: warning: Function 'reloginViaEmailFactory(email:)' is unused

I believe this is used but it is being used via an any protocol, not via the concrete class. If we didn't make such heavy use of existential any I guess this tool would prove more useful.

If we do find a good use for it I would consider ignoring files that are fairly recent (within 3 months for example) to avoid flagging WIP work

@WilhelmOks
Copy link
Collaborator

I changed the Python script to a Swift script to remove the dependency on Python. Swift should be available on any mac environment by default.

@OlivellaO
Copy link
Collaborator Author

So I'm a bit torn about adding Periphery to the project.

I really like periphery as a tool but don't really know how to make best use of it. For example we currently see that it identifies about 6000 issues. But these contain quite a lot of false positives/negatives as far as I know. For example:

WireAuthentication/Sources/WireAuthentication/Components/RootComponent.swift:134:10: warning: Function 'reloginViaEmailFactory(email:)' is unused

I believe this is used but it is being used via an any protocol, not via the concrete class. If we didn't make such heavy use of existential any I guess this tool would prove more useful.

If we do find a good use for it I would consider ignoring files that are fairly recent (within 3 months for example) to avoid flagging WIP work

Yeah, using any doesn't help identify unused code and will lead to some false positives/negatives. I don't have an strong opinion on this, i will say try to avoid any if possible.

For WIP code it's normal (and good) that you get some warnings and it makes you be aware if you're missing an implementation or not using a param you've added before, so i think it will help. Periphery also offers some annotations to @supress the warning for some specific code you're working on if it's really necessary.

@@ -0,0 +1,248 @@
#!/usr/bin/env swift
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header is required for the swift script but it's marked as an error by the github actions.
Can we disable the check somehow or add an exception or suppress rule?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WilhelmOks you should add the header:

//
// Wire
// Copyright (C) 2025 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as it is part of the project

@github-actions
Copy link
Contributor

This PR is stale because it has been open 30 days with no activity. Please update it or close it in case is not relevant anymore.

@github-actions github-actions bot added the stale label Nov 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants