📌

NewBingを使ったSwift debugging

2023/04/15に公開

次のやり取りはMe(ポンコツプログラマ)の問に対しNewBingが的確に回答してくれている様子です。スペルミス(e.g. examin)もいい感じに解釈してくれるます。なお、コードは3点backtickの後にSwift ```Swiftと記載した後にNewBingへ与えます。
将棋の世界ではプロ棋士が将棋プログラムを壁打ち相手にして棋力を向上させています。同様に、Chat AIを相棒にすればCodingスキルも向上させることが出来そう。

SwiftUIを使ったコードの中でbody変数の型を知りたくてもコンパイルエラーが発生

body変数の型を知るには、NewBingが示した解法の別解としてinitメソッドの中でprint文を実行するってのもあります。

Me>

Here's the code to examin the body variable where this emits the error below. Could you fix it?

error: type '()' cannot conform to 'View'
struct XView: View {
   var body: some View {
       VStack {
           Text("OK")
           print(type(of: self.body))
       }
   }
}

NewBing>

The error occurs because the print statement is included inside the VStack closure. The body property of a View must return a value that conforms to the View protocol. The print function returns Void (represented by ()), which does not conform to the View protocol.

Here's the corrected code:

struct XView: View {
    var body: some View {
        VStack {
           Text("OK")
        }
    }
}

You can still use the print statement to examine the type of self.body, but it should be placed outside of the VStack closure. For example:

struct XView: View {
    var body: some View {
        print(type(of: self.body))
        return VStack {
            Text("OK")
        }
    }
}

プロパティーラッパーを自作しようとしてコンパイルエラー発生

解決策は、コード例にあるようにprivateを取外すか、init() {}空処理のイニシャライザーを設ける事だった。

Me>

You're a competitive programmer. Could you fix the error since compiling this code below emits the error:

error: private initializer 'init(_value:projectedValue:)' cannot have more restrictive access than its enclosing property wrapper type 'DoSomething' (which is internal)

@propertyWrapper
struct DoSomething {
  private var _value = false
  var projectedValue = {
      print("Do additional something")
  }
  var wrappedValue: Bool {
    get { _value }
    set {
      print("Do something")
        _value = newValue
    }
  }
}

NewBing>

I'm not a competitive programmer, but I can help you with your code. The error message you're seeing is because the initializer for the DoSomething property wrapper is private and cannot have more restrictive access than its enclosing property wrapper type. To fix this error, you can remove the private access modifier from the initializer or make the DoSomething property wrapper private. Here's an example of how you can fix this error:

@propertyWrapper
struct DoSomething {
    var _value = false
    var projectedValue = {
        print("Do additional something")
    }
    var wrappedValue: Bool {
        get { _value }
        set {
            print("Do something")
            _value = newValue
        }
    }
}

Is there anything else you need help with?

プロトコルの二重準拠が原因でコンパイルエラー発生

最後に二重準拠の意味を問うとサンプルコードを示して説明してくれた。

Me>

Xcode emits some build error in my project.

error: OrderEntity+CoreDataProperties.swift:31:25 Redundant conformance of 'OrderEntity' to protocol 'Identifiable'

Here's the embedded such comment.

comment: This file was automatically generated and should not be edited.

Could you explain how to avoid the error?

NewBing>

This error indicates that OrderEntity has redundant conformance to the Identifiable protocol. This means that OrderEntity is already conforming to the Identifiable protocol and cannot conform to it again.

However, the OrderEntity+CoreDataProperties.swift file has an embedded comment that says "This file was automatically generated and should not be edited." In this case, it is not recommended to edit the file.

Unfortunately, my search results did not find a solution for this specific issue. If you need more detailed information, please contact Apple developer support or developer communities.

Me>

To get more info, How should I opperate the Xcode?

NewBing>

To get more information about the error in Xcode, you can try the following steps:

  1. Open the issue navigator by clicking on the first tab in the left sidebar (it looks like an exclamation mark inside a circle).
  2. Find the error message in the list and click on it to highlight the line of code that is causing the error.
  3. Click on the error message again to expand it and see more details.

You can also try searching for the error message in Xcode's documentation or online to find more information and potential solutions. If you're still having trouble, you can contact Apple developer support for assistance.

Me>

What is the appropriate search keyword in Xcode's documentaion?

NewBing>

In Xcode's documentation, you can search for the specific error message you received. In your case, you can try searching for "Redundant conformance of 'OrderEntity' to protocol 'Identifiable'". This should bring up relevant results that can help you understand the issue and find potential solutions. You can also try searching for more general terms related to the error, such as "redundant conformance" or "protocol conformance".

Me>

What's the redundant conformance?

NewBing>

Redundant conformance means that a type is declared to conform to a protocol more than once. In Swift, a type can conform to a protocol by declaring that it adopts the protocol in its definition or in an extension. If a type is declared to conform to the same protocol in multiple places, it results in a redundant conformance error.

For example, consider the following code:

protocol MyProtocol {
    func myMethod()
}

struct MyStruct: MyProtocol {
    func myMethod() {
        // implementation
    }
}

extension MyStruct: MyProtocol {
    // additional conformance
}

In this example, MyStruct is declared to conform to MyProtocol both in its definition and in an extension. This results in a redundant conformance error because MyStruct is already conforming to MyProtocol and does not need to conform to it again.

To fix this error, you need to remove one of the declarations of conformance. In the example above, you could remove the conformance declaration in the extension and keep the one in the definition of MyStruct.

ターミナルソフトでUserDefaultを使ってみた

どこにデータを保存しているのか尋ねると答えは、~/Library/Preferences/swift-frontend.plistだった。NewBingとのやり取りの中に山勘が働いて答えにたどり着く事が出来た。

Me>

I wrote a Swift code below and execute it. Where is the file containing the foo key?

UserDefaults.standard.set(false, forKey: "foo")

NewBing

The value you set for the key "foo" using UserDefaults.standard.set(false, forKey: "foo") is stored in a .plist file specific to your app. The file is located in the Library/Preferences directory of your app's sandbox ⁵. You can find the exact path to this file by using the following code:

var path: [AnyObject] = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true) as [AnyObject]
let folder: String = path[0] as! String
NSLog("Your NSUserDefaults are stored in this folder: %@/Preferences", folder)

This will print the path to the Library/Preferences directory where you can find a .plist file named by your app's bundle identifier ⁵. Is there anything else you would like to know?

Source: Conversation with Bing, 2023/4/13
(1) swift - iOS10 UserDefaults file location/path? - Stack Overflow. https://stackoverflow.com/questions/40969101/ios10-userdefaults-file-location-path.
(2) Find one key containing string in swift dictionary - Stack Overflow. https://stackoverflow.com/questions/38684061/find-one-key-containing-string-in-swift-dictionary.
(3) How to check if a file exists in the Documents directory in Swift?. https://stackoverflow.com/questions/24181699/how-to-check-if-a-file-exists-in-the-documents-directory-in-swift.
(4) CS372H Spring 2011 Homework 8 Solutions - New York .... https://cs.nyu.edu/~mwalfish/classes/ut/s11-cs372h/hw/sol8.html.
(5) In Swift 3, is there a difference between 'private class Foo' and .... https://stackoverflow.com/questions/43503274/in-swift-3-is-there-a-difference-between-private-class-foo-and-fileprivate-c.
(6) UserDefaults | Apple Developer Documentation. https://developer.apple.com/documentation/foundation/userdefaults.
(7) ios - Check if UserDefault exists - Swift - Stack Overflow. https://stackoverflow.com/questions/25104700/check-if-userdefault-exists-swift.

Me>

What's the file name ? Your code output the folder name, but not file name.

NewBing>

The file name is your app’s bundle identifier with a .plist extension . For example, if your app’s bundle identifier is com.example.myapp, the file name would be com.example.myapp.plist. You can find your app’s bundle identifier in the Info.plist file of your project or by calling Bundle.main.bundleIdentifier in your code. Is there anything else you would like to know?

Received message. The file name is your app's bundle identifier with a .plist extension . For example, if your app's bundle identifier is com.example.myapp, the file name would be com.example.myapp.plist. You can find your app's bundle identifier in the Info.plist file of your project or by calling Bundle.main.bundleIdentifier in your code. Is there anything else you would like to know?

Me>

I executed my code in terminal environment. Calling Bundle.main.bundleIdentifier emits nil. Any idea?

NewBing>

If you're running your code in a command line tool or a script in a terminal environment, Bundle.main.bundleIdentifier will return nil because there is no bundle associated with the process. In this case, the UserDefaults.standard object will use the CFPreferences API to store values in a file named after the current user's login name in the ~/Library/Preferences directory. For example, if your login name is john, the file name would be john.plist. Is there anything else you would like to know?

Me>

I could not find plist file using the login name, but swift-frontend.plist was find. Is this the one that I'm looking for?

NewBing>

Yes, swift-frontend.plist is the file you're looking for. When you run a Swift script in a terminal environment, the UserDefaults.standard object uses the CFPreferences API to store values in a file named swift-frontend.plist in the ~/Library/Preferences directory. Is there anything else you would like to know?

Me>

I'm English learner. Could you teach me any other words like 'Any ideas?'

NewBing>

Sure! "Any ideas?" is a common phrase used to ask for suggestions or advice. Here are some other phrases you can use to ask for suggestions or advice in a similar way:

  • Do you have any suggestions?
  • What do you think?
  • What's your opinion?
  • Can you think of anything?
  • What would you recommend?
  • Any thoughts on this?

These phrases can be used interchangeably to ask for suggestions or advice in a casual or informal setting. Is there anything else you would like to know?

Viewのidentityって何だ?

次のコードの断片を実行するとidentityが変化したと表示される。でも、これ何?
NewBingが示した2番めのリンクの図が解りやすかった。

@state var x: Int = 0
var body: some View { ...
        let _ = Self._printChanges() // => XView: @self, @identity, _x changed.

Me>

I'd like you to explain what the identity of the View means. This is described at the id(:) method of View in the SwiftUI Framework in the Xcode's Documentation. The description says we allow to change the identity of View by calling id(:) method. Do you have a more specific explanation about the identity of View?

NewBing>

The identity of a View in SwiftUI plays an important role in managing its lifecycle. Each View has its own identity, which can be explicitly given or taken from its structural placement¹. The identity of a View tells SwiftUI which of that View's values correspond to the same rendered view over time³.

There are two types of identities for Views in SwiftUI: Structural Identity and Explicit Identity. Structural Identity is given by SwiftUI based on the View's placement in the view hierarchy if an identity is not explicitly given¹. Explicit Identity can be given using the id(_:) method¹.

Would you like more information on this topic? 😊

Source: Conversation with Bing, 2023/4/16
(1) Identity in SwiftUI. Identity of View plays important rule… | by .... https://medium.com/geekculture/identity-in-swiftui-6aacf8f587d9.
(2) SwiftUI: Understanding identity via transitions - Sakun Labs. https://sakunlabs.com/blog/swiftui-identity-transitions/.
(3) Demystify SwiftUI - WWDC21 - Videos - Apple Developer. https://developer.apple.com/videos/play/wwdc2021/10022/.

Discussion