<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Liang Wang</title>
    <description>The latest articles on DEV Community by Liang Wang (@liangtowang).</description>
    <link>https://dev.to/liangtowang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1255533%2F76d3d6fe-13c1-4854-b86b-b27d43a32076.png</url>
      <title>DEV Community: Liang Wang</title>
      <link>https://dev.to/liangtowang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/liangtowang"/>
    <language>en</language>
    <item>
      <title>defer</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Sun, 08 Jun 2025 19:39:28 +0000</pubDate>
      <link>https://dev.to/liangtowang/defer-5330</link>
      <guid>https://dev.to/liangtowang/defer-5330</guid>
      <description>&lt;p&gt;I am using photoPicker to select an image from photo library, and before using defer, my code looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PhotosPicker(selection: $selectedItem, matching: .images) {
                            Label("Select an image", systemImage: "photo")
                        }
                        .onChange(of: selectedItem) { _, newValue in
                            isLoadingImage = true
                            Task {
                                    if let data = try? await newValue?.loadTransferable(type: Data.self) {
                                        selectedImageData = data

                                        if let selectedImageData, let uiImage = UIImage(data: selectedImageData) {
                                            inputImage = uiImage
                                        }
                                    }
                                isLoadingImage = false
                            } //: Task
                        } //: onChange
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After using defer and change try? to do { try } catch { }, my code now looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PhotosPicker(selection: $selectedItem, matching: .images) {
                            Label("Select an image", systemImage: "photo")
                        }
                        .onChange(of: selectedItem) { _, newValue in
                            Task {
                                isLoadingImage = true
                                defer { isLoadingImage = false }

                                do {
                                    if let data = try await newValue?.loadTransferable(type: Data.self) {
                                        selectedImageData = data

                                        if let selectedImageData, let uiImage = UIImage(data: selectedImageData) {
                                            inputImage = uiImage
                                        }
                                    }
                                } catch {
                                    print("Failed to load image: \(error.localizedDescription)")
                                }
                            } //: Task
                        } //: onChange
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>swiftui</category>
    </item>
    <item>
      <title>do try catch</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Sun, 08 Jun 2025 19:37:40 +0000</pubDate>
      <link>https://dev.to/liangtowang/do-try-catch-4709</link>
      <guid>https://dev.to/liangtowang/do-try-catch-4709</guid>
      <description>&lt;p&gt;use do { try ... } catch { ... }&lt;br&gt;
or ignore the error just by using try?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;do {
    try modelContext.save()
    print("Item updated.")
} catch {
    print("Failed to edit item: \(error.localizedDescription)")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or just use try? modelContext.save()&lt;/p&gt;

</description>
      <category>swifui</category>
    </item>
    <item>
      <title>Non-sendable result type cannot be sent from nonisolated context in call to instance method</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Thu, 05 Jun 2025 20:39:39 +0000</pubDate>
      <link>https://dev.to/liangtowang/non-sendable-result-type-cannot-be-sent-from-nonisolated-context-in-call-to-instance-method-4o4a</link>
      <guid>https://dev.to/liangtowang/non-sendable-result-type-cannot-be-sent-from-nonisolated-context-in-call-to-instance-method-4o4a</guid>
      <description>&lt;p&gt;My class: Element&lt;/p&gt;

&lt;p&gt;** The Problem:** &lt;br&gt;
&lt;code&gt;Non-sendable result type '[Element]' cannot be sent from nonisolated context in call to instance method 'fetchData(from:)'; this is an error in the Swift 6 language mode&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; &lt;br&gt;
Mark class Element as final, and conform to protocol Sendable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New problem:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Stored property '_id' of 'Sendable'-conforming class '...' is mutable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New Solution:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;use @unchecked Sendable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Link: &lt;a href="https://blog.vapor.codes/posts/fluent-models-and-sendable/" rel="noopener noreferrer"&gt;https://blog.vapor.codes/posts/fluent-models-and-sendable/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>swiftui</category>
    </item>
    <item>
      <title>TabView array id</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Sat, 31 May 2025 10:38:44 +0000</pubDate>
      <link>https://dev.to/liangtowang/tabview-array-id-p5m</link>
      <guid>https://dev.to/liangtowang/tabview-array-id-p5m</guid>
      <description>&lt;p&gt;TabView items need to have a unique and persistent ID for the item in each tab view to swipe. &lt;/p&gt;

&lt;p&gt;It cannot be computed property.&lt;/p&gt;

</description>
      <category>swiftui</category>
    </item>
    <item>
      <title>iOS 18.4 Simulator Error</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Fri, 30 May 2025 23:21:44 +0000</pubDate>
      <link>https://dev.to/liangtowang/ios-184-simulator-error-4d87</link>
      <guid>https://dev.to/liangtowang/ios-184-simulator-error-4d87</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL: DR&lt;/strong&gt;&lt;br&gt;
Use a physical iPhone or an older simulator if you are having trouble using the latest iOS 18.4 simulator parsing data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am working on an iOS app that uses Firebase Hosting for my json files and images, I want to load the data and cache them in SwiftData. In the beginning I thought Firebase Hosting works great for me, simple firebase deploy is all that needed to keep the files updated, no more git commits for Github pages where I used to store the files.&lt;/p&gt;

&lt;p&gt;But, there can be problem with Firebase Hosting CDN caching the files, so it is best the set firebase no-cache.&lt;/p&gt;

&lt;p&gt;Then in my iPhone 16 Pro iOS 18.4 simulator, I noticed that the json data could not be parsed. I tried with several simulators of iOS 18.4, all have the same problem. But there is no problem of fetching and parsing data when I use a physical iPhone with iOS 18.4. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Research&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Later I find out that this is a known issue with the latest macOS and iOS simulators, especially with Xcode 15.3+ and macOS Sonoma.&lt;/p&gt;

&lt;p&gt;My simulator logs show:&lt;br&gt;
• network connection was lost&lt;br&gt;
• no local endpoint&lt;br&gt;
• Server protocol violation&lt;br&gt;
• SwiftData warning about ModelContext on the wrong thread&lt;br&gt;
• It fails on the macOS target or newer iOS simulators, but works fine on older simulators like iOS 18.0 / iPhone 12 Pro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So now I stick with the iPhone 12 Pro simulator on iOS 18.0 while Apple and Firebase resolve the instability on newer platforms.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Today I learned</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Thu, 08 May 2025 12:50:21 +0000</pubDate>
      <link>https://dev.to/liangtowang/today-i-learned-3e3c</link>
      <guid>https://dev.to/liangtowang/today-i-learned-3e3c</guid>
      <description>&lt;p&gt;Today I learned&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Azure key vault to store secrets there, such as sensitive information like this: process.env.AzureToken&lt;/li&gt;
&lt;li&gt;Set up azure pipeline for playwright to run at 7AM&lt;/li&gt;
&lt;li&gt;Add Eslint for typescript and playwright&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tip:&lt;br&gt;
When set up azure pipeline for playwright, remember that it needs to be in the right working directory, otherwise npm ci can not find the package-lock.json file and cannot run.&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>azure</category>
      <category>playwright</category>
      <category>devops</category>
    </item>
    <item>
      <title>Add SwiftLint to Xcode 15.4 on M1 Mac</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Tue, 06 Aug 2024 18:09:17 +0000</pubDate>
      <link>https://dev.to/liangtowang/add-swiftlint-to-xcode-on-m1-mac-m4l</link>
      <guid>https://dev.to/liangtowang/add-swiftlint-to-xcode-on-m1-mac-m4l</guid>
      <description>&lt;p&gt;I noticed that SwiftLint no longer works for me in Xcode 15.4 when I switched to a M1 Mac, so I searched and found this user script that has helped me to resolve this problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install SwiftLint&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install swiftlint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Add new run script phrase&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if [[ "$(uname -m)" == arm64 ]]; then
    export PATH="/opt/homebrew/bin:$PATH"
fi

if which swiftlint &amp;gt; /dev/null; then
  swiftlint --fix &amp;amp;&amp;amp; swiftlint
else
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Disable User Script Sandboxing&lt;/strong&gt;&lt;br&gt;
Do not forget to disable User Script Sandboxing in Build Settings/Build options, which is enabled by default from XCode 15.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Swiftlint rules&lt;/strong&gt;&lt;br&gt;
Update the line_length warning and error so it works for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;disabled_rules:
- trailing_whitespace
opt_in_rules:
- empty_count
- empty_string
excluded:
- Carthage
- Pods
- SwiftLint/Common/3rdPartyLib
line_length:
    warning: 300
    error: 500
    ignores_function_declarations: true
    ignores_comments: true
    ignores_urls: true
function_body_length:
    warning: 300
    error: 500
function_parameter_count:
    warning: 10
    error: 15
type_body_length:
    warning: 300
    error: 500
file_length:
    warning: 1000
    error: 1500
    ignore_comment_only_lines: true
cyclomatic_complexity:
    warning: 15
    error: 25
reporter: "xcode"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SwiftLint disable rule&lt;/strong&gt;&lt;br&gt;
For example, &lt;code&gt;// swiftlint:disable:next identifier_name&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Custom VS Code hot key</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Thu, 02 May 2024 11:26:08 +0000</pubDate>
      <link>https://dev.to/liangtowang/custom-vs-code-hot-key-1h82</link>
      <guid>https://dev.to/liangtowang/custom-vs-code-hot-key-1h82</guid>
      <description>&lt;p&gt;I would like to set up my own hot key to run and to cancel current test file.&lt;/p&gt;

&lt;p&gt;First, press &lt;code&gt;ctrl K ctrl S&lt;/code&gt; to show the keyboard shortcuts&lt;/p&gt;

&lt;p&gt;To set up hotkey for run current test file&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search for "Run tests in current file" to find "testing.runCurrentFile" command&lt;/li&gt;
&lt;li&gt;press "Enter" to change keybinding to your own hotkey, i.e. "Shift + Alt + R"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To set up hotkey for cancel current test file&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search for "Cancel run" to find "testing.cancelRun" command&lt;/li&gt;
&lt;li&gt;press "Enter" to change keybinding to your own hotkey, i.e. "Shift + Alt + S"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So now you can use your own hotkey to start test run and cancel test run if it hangs.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Global Git configuration</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Thu, 11 Apr 2024 14:21:54 +0000</pubDate>
      <link>https://dev.to/liangtowang/global-git-configuration-54fg</link>
      <guid>https://dev.to/liangtowang/global-git-configuration-54fg</guid>
      <description>&lt;p&gt;&lt;code&gt;git config --list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Alias I use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias.br=branch
alias.co=checkout
alias.cm=commit
alias.st=status
alias.last=log -3 --color --graph --pretty=format:'%Cred%h%Creset %C(yellow)%d%Creset %n%s %n%Cgreen(%cr) %n%C(bold blue)&amp;lt;%an&amp;gt;%Creset%n' --abbrev-commit --branches
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Disable auto line break in VS Code</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Mon, 19 Feb 2024 08:54:17 +0000</pubDate>
      <link>https://dev.to/liangtowang/disable-auto-line-break-in-vs-code-4fo</link>
      <guid>https://dev.to/liangtowang/disable-auto-line-break-in-vs-code-4fo</guid>
      <description>&lt;p&gt;To disable the auto line break in the VS code.&lt;br&gt;
Are you struggling to disable the auto line break in vs code from the Prettier extension? If yes this is for you :)&lt;/p&gt;

&lt;p&gt;Open vs code =&amp;gt; Code =&amp;gt; Preferences =&amp;gt; Settings =&amp;gt; In the search field type: Prettier&lt;br&gt;
Now from the provided Prettier settings, choose the Prettier: Print Width&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xtjardr13jwmqqrm839.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xtjardr13jwmqqrm839.png" alt="Image description" width="301" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Screenshot&lt;br&gt;
And Instead of 80, you can make it a big number. Eg: 999999&lt;br&gt;
Now you don't have to worry about the line break.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.reddit.com/r/vscode/comments/lkz3d7/to_disable_the_auto_line_break_in_the_vs_code/" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>npm</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Sat, 17 Feb 2024 09:35:03 +0000</pubDate>
      <link>https://dev.to/liangtowang/npm-4a9a</link>
      <guid>https://dev.to/liangtowang/npm-4a9a</guid>
      <description>&lt;p&gt;&lt;a href="https://nodejs.org/en/download/package-manager#macos" rel="noopener noreferrer"&gt;Install node on Mac&lt;/a&gt;&lt;br&gt;
n&lt;/p&gt;

&lt;p&gt;n is a simple to use Node.js version manager for Mac and Linux. Specify the target version to install using a rich syntax, or select from a menu of previously downloaded versions. The versions are installed system-wide or user-wide, and for more targeted use you can run a version directly from the cached downloads.&lt;/p&gt;

&lt;p&gt;See the homepage for install methods (bootstrap, npm, Homebrew, third-party), and all the usage details.&lt;/p&gt;

&lt;p&gt;If you already have npm then installing n and then the newest LTS node version is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g n
n lts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Playwright if locator is visible</title>
      <dc:creator>Liang Wang</dc:creator>
      <pubDate>Fri, 16 Feb 2024 23:21:00 +0000</pubDate>
      <link>https://dev.to/liangtowang/playwright-if-locator-is-visible-3kdf</link>
      <guid>https://dev.to/liangtowang/playwright-if-locator-is-visible-3kdf</guid>
      <description>&lt;p&gt;I have a project that sometimes will throw an error when try to delete an object.&lt;br&gt;
I would like to catch that error and click on the OK button to close it.&lt;/p&gt;

&lt;p&gt;Here is what works for me.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const element = page.getByRole("button", { name: "OK" });
    if (await element.isVisible()) {
     await element.click();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
