<?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>Forem: Nakaoka Rei</title>
    <description>The latest articles on Forem by Nakaoka Rei (@nakaokarei).</description>
    <link>https://forem.com/nakaokarei</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%2F1015616%2F13b336c4-376d-47fe-822b-94b7dec4dab1.jpeg</url>
      <title>Forem: Nakaoka Rei</title>
      <link>https://forem.com/nakaokarei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nakaokarei"/>
    <language>en</language>
    <item>
      <title>XCTestGen: CLI for automatic XCTest generation using ChatGPT</title>
      <dc:creator>Nakaoka Rei</dc:creator>
      <pubDate>Tue, 14 Mar 2023 13:52:24 +0000</pubDate>
      <link>https://forem.com/nakaokarei/xctestgen-cli-for-automatic-xctest-generation-using-chatgpt-4gk1</link>
      <guid>https://forem.com/nakaokarei/xctestgen-cli-for-automatic-xctest-generation-using-chatgpt-4gk1</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;As the title suggests, I created a tool for automatic generation of Swift's XCTest using ChatGPT, which is very popular nowadays. I will briefly explain how I developed it and how to use it.&lt;br&gt;
I would be happy if you starred it.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/NakaokaRei"&gt;
        NakaokaRei
      &lt;/a&gt; / &lt;a href="https://github.com/NakaokaRei/XCTestGen"&gt;
        XCTestGen
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      CLI for automatic XCTest generation using ChatGPT
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
XCTestGen&lt;/h1&gt;
&lt;p&gt;CLI for automatic XCTest generation using ChatGPT&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/NakaokaRei/XCTestGen/issues"&gt;&lt;img src="https://camo.githubusercontent.com/77726c397d1bf48931d64870ecf8291a4351a439c49c85d1dd351ac464eacb3a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f4e616b616f6b615265692f58435465737447656e" alt="Github issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/XCTestGen/network/members"&gt;&lt;img src="https://camo.githubusercontent.com/0e0deffad8770e48b8729d53b22ce093e6d56a6448ca62e5aa1ccaf00c0cab30/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f4e616b616f6b615265692f58435465737447656e" alt="Github forks"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/XCTestGen/stargazers"&gt;&lt;img src="https://camo.githubusercontent.com/d12ebad5873d70118ac326b3554c218b0619fcb244c756088a9efafc6928f3ed/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f4e616b616f6b615265692f58435465737447656e" alt="Github stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/XCTestGen/"&gt;&lt;img src="https://camo.githubusercontent.com/0fd679bdbd004f7615682438b791073273ebb0f157a23c91bfc46ddb6283a3af/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f746f702f4e616b616f6b615265692f58435465737447656e" alt="Github top language"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/XCTestGen/"&gt;&lt;img src="https://camo.githubusercontent.com/83b9ec27d88b4c1217a5e8c0b3a0e607d1d026ef9cdcf225db371bbe0a32828e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f4e616b616f6b615265692f58435465737447656e" alt="Github license"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
Installation&lt;/h1&gt;
&lt;p&gt;Execute the following command from above.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ git clone git@github.com:NakaokaRei/XCTestGen.git
$ cd XCTestGen
$ swift build -c release
$ cp .build/release/XCTestGen /usr/local/bin/XCTestGen
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;
Usage&lt;/h1&gt;
&lt;p&gt;Executing the command with the path of the input file and the path of the destination folder will save the unit test code in the destination folder.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ XCTestGen $OPENAI_KEY "input file path" "output dir path"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;e.g. If &lt;code&gt;Sample.swift&lt;/code&gt; is input, &lt;code&gt;SampleTests.swift&lt;/code&gt; will be created in the output destination.&lt;/p&gt;
&lt;div class="highlight highlight-source-swift notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; Sample.swift&lt;/span&gt;
&lt;span class="pl-k"&gt;class&lt;/span&gt; &lt;span class="pl-en"&gt;Sample&lt;/span&gt; {
    &lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;sample1&lt;/span&gt;(&lt;span class="pl-smi"&gt;&lt;span class="pl-en"&gt;x&lt;/span&gt;&lt;/span&gt;: &lt;span class="pl-c1"&gt;Int&lt;/span&gt;) &lt;span class="pl-k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="pl-c1"&gt;Int&lt;/span&gt; {
        &lt;span class="pl-k"&gt;return&lt;/span&gt; x &lt;span class="pl-k"&gt;+&lt;/span&gt; &lt;span class="pl-c1"&gt;1&lt;/span&gt;
    }

    &lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;sample2&lt;/span&gt;(&lt;span class="pl-smi"&gt;&lt;span class="pl-en"&gt;x&lt;/span&gt;&lt;/span&gt;: &lt;span class="pl-c1"&gt;String&lt;/span&gt;) &lt;span class="pl-k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="pl-c1"&gt;String&lt;/span&gt; {
        &lt;span class="pl-k"&gt;return&lt;/span&gt; x &lt;span class="pl-k"&gt;+&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;sample&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;
    }
}&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-swift notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; SampleTests.swift&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-en"&gt;XCTest&lt;/span&gt;
&lt;span class="pl-k"&gt;class&lt;/span&gt; &lt;span class="pl-en"&gt;SampleTests&lt;/span&gt;: &lt;span class="pl-e"&gt;XCTestCase &lt;/span&gt;{

    &lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;test_sample1&lt;/span&gt;() {
        &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; given&lt;/span&gt;
        &lt;span class="pl-k"&gt;let&lt;/span&gt; expectedResult &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-c1"&gt;11&lt;/span&gt;
        &lt;span class="pl-k"&gt;let&lt;/span&gt; sampleInput &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-c1"&gt;10&lt;/span&gt;
        &lt;span class="pl-k"&gt;let&lt;/span&gt; sut &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-c1"&gt;Sample&lt;/span&gt;()

        &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; when&lt;/span&gt;
        &lt;span class="pl-k"&gt;let&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/NakaokaRei/XCTestGen"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Creation of CLI tools
&lt;/h1&gt;

&lt;p&gt;Using Swift Packages, we have created a CLI tool. The template is created by executing the following command under the working directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ swift package init --type executable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Automatic generation of XCTest
&lt;/h1&gt;

&lt;p&gt;As the title suggests, ChatGPT is used for automatic generation of XCTests, and the following commands are given to ChatGPT to write XCTest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please write a unit test (XCTest) of the following Swift code. No explanatory text is required as we would like to save your output as source code as is.

// Sample.swift
class Sample {
    func sample(input: String) -&amp;gt; String {
    // 任意の処理
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following libraries were used to utilize OpenAI's API in Swift.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/adamrushy/OpenAISwift"&gt;https://github.com/adamrushy/OpenAISwift&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Throw the above instruction to ChatGPT and save the response in the specified folder. If you want to know more details, please see the &lt;a href="https://github.com/NakaokaRei/XCTestGen/blob/c11ff20bf5a44f5073ec06967325367b663a5afd/Sources/XCTestGen/XCTestGen.swift#L33"&gt;code&lt;/a&gt; in the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;generateXCTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;throws&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Please write a unit test (XCTest) of the following Swift code. No explanatory text is required as we would like to save your output as source code as is."&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

        &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;FileManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readTextFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;atPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="kt"&gt;XCTestGenError&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readCodeError&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;openAI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;OpenAISwift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;openAI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendCompletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;maxTokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;maxTokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;testCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="kt"&gt;XCTestGenError&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chatgptResultError&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;FileManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;saveTextFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;testCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;atPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;outputTestsPath&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="kt"&gt;XCTestGenError&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;saveFileError&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Execute the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone git@github.com:NakaokaRei/XCTestGen.git
$ cd XCTestGen
$ swift build -c release
$ cp .build/release/XCTestGen /usr/local/bin/XCTestGen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generate XCTest
&lt;/h2&gt;

&lt;p&gt;Execute the following command. In order from the first argument, "API Key of OpenAI", "Path of the Swift file for which you want to automatically generate tests", and "Directory of the output destination".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ XCTestGen $OPENAI_KEY "input file path" "output dir path"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you give the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sample.swift&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Sample&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;sample1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;sample2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"sample"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following code is generated and saved&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SampleTests.swift&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;XCTest&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;SampleTests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;XCTestCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;test_sample1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// given&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;expectedResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;sampleInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;sut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// when&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sampleInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// then&lt;/span&gt;
        &lt;span class="kt"&gt;XCTAssertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expectedResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;test_sample2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// given&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;expectedResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"testsample"&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;sampleInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;sut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Sample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// when&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sample2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sampleInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// then&lt;/span&gt;
        &lt;span class="kt"&gt;XCTAssertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expectedResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The current issue is that the test code generated from ChatGPT is not checked for grammatical correctness, so I think it would be better to use SwiftLint or other tools to perform at least some checks.&lt;br&gt;
In the future, we plan to add a plugin function to Swift Package Manger so that it can be easily introduced into Xcode projects.&lt;/p&gt;

&lt;p&gt;I'm waiting for Issue and PR!!!!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>chatgpt</category>
      <category>openai</category>
      <category>cli</category>
    </item>
    <item>
      <title>SwiftAutoGUI: Library for manipulating macOS with Swift</title>
      <dc:creator>Nakaoka Rei</dc:creator>
      <pubDate>Fri, 27 Jan 2023 12:08:36 +0000</pubDate>
      <link>https://forem.com/nakaokarei/swiftautogui-library-for-manipulating-macos-with-swift-15nm</link>
      <guid>https://forem.com/nakaokarei/swiftautogui-library-for-manipulating-macos-with-swift-15nm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I developed library for manipulating macOS with Swift. In this article, I will explain usage.&lt;/p&gt;

&lt;p&gt;If you think it's good, star me!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/NakaokaRei"&gt;
        NakaokaRei
      &lt;/a&gt; / &lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI"&gt;
        SwiftAutoGUI
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Used to programmatically control the mouse &amp;amp; keyboard.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
SwiftAutoGUI&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/5bdd285df0ad6b5505f40fe4a4ea14e7c336fcce8cd643058a8d268d6080f3a8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53504d2d537570706f727465642d6f72616e6765"&gt;&lt;img src="https://camo.githubusercontent.com/5bdd285df0ad6b5505f40fe4a4ea14e7c336fcce8cd643058a8d268d6080f3a8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53504d2d537570706f727465642d6f72616e6765" alt="SPM is supported"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI/issues"&gt;&lt;img src="https://camo.githubusercontent.com/f61b92e89828d474298e47ddee4b95d18ac7a96bada58dd8c9c18ba1003851f4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f4e616b616f6b615265692f53776966744175746f475549" alt="Github issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI/network/members"&gt;&lt;img src="https://camo.githubusercontent.com/bd439578641b7a35b6f411446f307a6671c2a8da15e7717167d59df414d7dab8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f4e616b616f6b615265692f53776966744175746f475549" alt="Github forks"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI/stargazers"&gt;&lt;img src="https://camo.githubusercontent.com/7622bdfb6fb0ffd079a6e43137ca59541dbc4fcc444829ab3e3d44bb9fad8d07/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f4e616b616f6b615265692f53776966744175746f475549" alt="Github stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI/"&gt;&lt;img src="https://camo.githubusercontent.com/04d582b4e4c07350823d4bd7a68509789248fe8101b52aa0a149609930cc9cc1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f746f702f4e616b616f6b615265692f53776966744175746f475549" alt="Github top language"&gt;&lt;/a&gt;
&lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI/"&gt;&lt;img src="https://camo.githubusercontent.com/5ac8b2ff3cbb6bc8162349a1a6813fce3f0d6670a8603d26c4c43fe74b1d4f0e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f4e616b616f6b615265692f53776966744175746f475549" alt="Github license"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Used to programmatically control the mouse &amp;amp; keyboard
A library for manipulating macOS with Swift.&lt;/p&gt;
&lt;p&gt;This repository is implemented with reference to &lt;a href="https://github.com/asweigart/pyautogui"&gt;pyautogui&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
Installation&lt;/h1&gt;
&lt;p&gt;SwiftAutoGUI is available through &lt;a href="https://www.swift.org/package-manager/" rel="nofollow"&gt;Swift Package Manager&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;in &lt;code&gt;Package.swift&lt;/code&gt; add the following:&lt;/p&gt;
&lt;div class="highlight highlight-source-swift notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;dependencies&lt;span class="pl-k"&gt;:&lt;/span&gt; [
    &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; Dependencies declare other packages that this package depends on.&lt;/span&gt;
    .&lt;span class="pl-c1"&gt;package&lt;/span&gt;(&lt;span class="pl-c1"&gt;url&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;https://github.com/NakaokaRei/SwiftAutoGUI&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;span class="pl-c1"&gt;branch&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;master&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;)
],
targets&lt;span class="pl-k"&gt;:&lt;/span&gt; [
    .&lt;span class="pl-c1"&gt;target&lt;/span&gt;(
        &lt;span class="pl-c1"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;MyProject&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;,
        &lt;span class="pl-c1"&gt;dependencies&lt;/span&gt;: [&lt;span class="pl-k"&gt;...&lt;/span&gt;, &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;SwiftAutoGUI&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;]
    )
    &lt;span class="pl-k"&gt;...&lt;/span&gt;
]&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
Example Usage&lt;/h1&gt;
&lt;h2&gt;
Keyboard and Mouse Control&lt;/h2&gt;
&lt;p&gt;See &lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI/Sources/SwiftAutoGUI/Keycode.swift"&gt;Keycode.swift&lt;/a&gt; for supported keys.
If it is not a US keyboard, This may not work properly.&lt;/p&gt;
&lt;div class="highlight highlight-source-swift notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-en"&gt;SwiftAutoGUI&lt;/span&gt;
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; Send ctrl + ←&lt;/span&gt;
SwiftAutoGUI.&lt;span class="pl-c1"&gt;sendKeyShortcut&lt;/span&gt;([.&lt;span class="pl-smi"&gt;control&lt;/span&gt;, .&lt;span class="pl-smi"&gt;leftArrow&lt;/span&gt;])

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; Send sound up&lt;/span&gt;
SwiftAutoGUI.&lt;span class="pl-c1"&gt;keyDown&lt;/span&gt;(.&lt;span class="pl-smi"&gt;soundUp&lt;/span&gt;)
SwiftAutoGUI.&lt;span class="pl-c1"&gt;keyUp&lt;/span&gt;(.&lt;span class="pl-smi"&gt;soundUp&lt;/span&gt;)

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;//&lt;/span&gt; Move mouse by dx, dy&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/NakaokaRei/SwiftAutoGUI"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;SwiftAutoGUI is available through &lt;a href="https://www.swift.org/package-manager/"&gt;Swift Package Manager&lt;/a&gt;.　&lt;/p&gt;

&lt;p&gt;in &lt;code&gt;Package.swift&lt;/code&gt; add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Dependencies declare other packages that this package depends on.&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/NakaokaRei/SwiftAutoGUI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"master"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="nv"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"MyProject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SwiftAutoGUI"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keyboard
&lt;/h3&gt;

&lt;p&gt;By calling a method of the SwiftAutoGUI class as shown below, you can send key input commands to macOS. Supported keys are written in &lt;a href="https://github.com/NakaokaRei/SwiftAutoGUI/blob/master/Sources/SwiftAutoGUI/Keycode.swift"&gt;Keycode.swift&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As shown in the sample below, you can also input shortcuts, such as moving the virtual desktop by sending the command &lt;code&gt;ctrl + ←&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;

&lt;span class="c1"&gt;// Send ctrl + ←&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendKeyShortcut&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leftArrow&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;// Send sound up&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keyDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;soundUp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keyUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;soundUp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mouse
&lt;/h3&gt;

&lt;p&gt;Similarly, mouse operations can generate basic commands such as mouse movement, clicking, and scrolling by invoking methods of the SwiftAutoGUI class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;

&lt;span class="c1"&gt;// Move mouse by dx, dy from the current location&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveMouse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Click where the mouse is located&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leftClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Scroll&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vscroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;clicks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// up&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vscroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;clicks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// down&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hscroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;clicks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// left&lt;/span&gt;
&lt;span class="kt"&gt;SwiftAutoGUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hscroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;clicks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// right&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In the future, we would like to add JIS keyboard support, support for other operating systems, and events.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>macos</category>
    </item>
  </channel>
</rss>
