I'm trying to port WKWebView over to SwiftUI. Here's my code:
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
WebViewWrapper()
}
}
/**
WKWebView ported over to SwiftUI with `UIViewRepresentable`.
*/
final class WebViewWrapper: UIViewRepresentable {
/// `UIViewRepresentable` required function #1.
func makeUIView(context: Context) -> WKWebView {
print("make")
let webView = WKWebView() /// EXC_BREAKPOINT error here
return webView
}
/// `UIViewRepresentable` required function #2
func updateUIView(_ uiView: WKWebView, context: Context) {
}
}
That's it. I created a new SwiftUI project and pasted it in. However, I get this error:
Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
... with nothing printed in the console. This happened for both iOS 13.0 and iOS 13.1.
But, on iOS 14.2, it works fine. The crash also seems to happen only for WKWebView. For example, if I replace it with UITextView, it runs without problems.
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
TextViewWrapper()
}
}
/**
UITextView ported over to SwiftUI with `UIViewRepresentable`.
*/
final class TextViewWrapper: UIViewRepresentable {
/// `UIViewRepresentable` required function #1.
func makeUIView(context: Context) -> UITextView {
print("make")
let textView = UITextView() /// no error, works fine
return textView
}
/// `UIViewRepresentable` required function #2
func updateUIView(_ uiView: UITextView, context: Context) {
}
}
I'm running Big Sur 11.0.1 on an M1 Mac, but I don't think that should be a problem. My Xcode version is 12.2 (12B45b).
Edit: Big Sur / M1 might be the problem.
I just ran it on the same version of Xcode on my Intel Mac, Catalina 10.15.5, and it works fine.
The problem is due to a combination of running on an M1 Mac and using an iOS version prior to 14. The problem is known to Apple.
I found a simple workaround.
Setting any of the following diagnostic options in the scheme settings will prevent the crash.
Address Sanitizer
Thread Sanitizer
Malloc Scribble
Malloc Guard Edges
Guard Malloc
Malloc Stack Logging
Diagnostic Options
I verified this with Xcode 12.4 (12D4e), iOS 13.7 Simulator, macOS Big Sur 11.2.3(20D91) and M1 Apple Silicon Mac.
Your UIViewRepresentable should be a struct not a class
struct WebViewWrapper: UIViewRepresentable {
^^^^^^
As not reproducible, just guessing... try different constructors, like
let wkWebConfiguration = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: wkWebConfiguration)
or even with some defined frame (anyway it does not matter later for SwiftUI view hierarchy)
let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: 100, height: 100),
configuration: wkWebConfiguration)
As Norman mentioned it's true if you are using xcode 12 and running simulator having ios version less than 14 it will break the application, it's problem with M1 chip. I my self test the application on 2 systems one on older mac and one on newer mac with m1 chip
I think this problem is solved with BigSur 11.3
Related
I'm made an very basic iOS Widget Extension with (on iOS 16):
struct TotoView: View
var body: some View {
VStack {
Text("Toto")
.font(.headline)
}
}
}
struct TotoWidget: Widget {
var body: some WidgetConfiguration {
IntentConfiguration(kind: "myKind", intent: ViewTodayIntent.self, provider: TimelineProvider()) { entry in
TotoView(entry: entry)
}
.configurationDisplayName("Today work")
.description("Show today work sessions")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
On the SwiftUI Canvas preview, I can see the "Toto" text.
BUT when I select the Widget Target and run in the simulator, I only have the placeholder in place of text. Any idea of why? Note that not only the text is replaced by placegholder but also an Image(systemName:)
I think the issue seems to be related by IntentConfiguration (as everything works fine with StaticConfiguration)
I'm on xCode 14.
In my Case it helped to change the Simulator. The Bug is still in my case on an iPhone 11 Simulator and on a real iPhone 11.
With other Simulators it works well.
Maybe its an issue with an iPhone 11.
I tried this:
let window = UIApplication.shared.windows.first
print("safeareatop: \(window?.safeAreaInsets.top)")
and get:
'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead
so I tried:
UIWindowScene.windows.first
but I get another error, the error messages from xcode are absolutely useless compared to android studios btw
the "solutions" from here:
Why it is throw an error as "'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead" in SwiftUI?
and here:
'windows' was deprecated in iOS 15.0
are still giving me this message.
So how to do this?
With access to window provided in reference (https://stackoverflow.com/a/60359809/12299030) works fine here.
Tested with Xcode 13.4 / iOS 15.5 / iPhone 12
Use GeometryReader
struct ContentView: View {
var body: some View {
GeometryReader { proxy in
Text("Something")
.onAppear {
print(proxy.safeAreaInsets)
}
}
}
}
When loading this view, the app crashes on iOS 13.2 and 13.3 with an EXC_BAD_INSTRUCTION error:
struct HomeView: View {
var body: some View {
NavigationView {
ScrollView {
// Some content
}.navigationBarTitle(
Text("home.title"),
displayMode: .inline
)
}
}
}
Removing the navigationBarTitle part entirely, or just the displayMode will prevent the app from crashing. This looks similar to this question, but just upgrading xcode doesn't fix the problem.
Another interesting thing to note is that if I remove this line in my ContentView's init() it does not crash:
UINavigationBar.appearance().isTranslucent = false
It is fixed in later versions of iOS 13 and iOS 14, but I have users on older versions of iOS complaining. Do you have any idea of what the problem could be ?
It's my first question on stackoverflow. Please correct me if I wrong with formatting topic.
I get crash of application when try use long press (?haptic touch?) on real iPad. Also it's reproducible on Simulators iPad with Force Touch click on Magic Trackpad.
Which devices have this bug?
Every iPad since iOS 13.4 until the last iOS 13.
Every Simulator iPad since iOS 13.4 until the last iOS 13.
I never saw this bug on iPhone.
My set up for testing: MacOS Catalina 10.15.6, xCode 11.7,
Simulator iPad mini 2019 5-gen iOS 13.7,
iPad 2018 6-gen iOS 13.7.
Upd 26.10.2020. Also, I try to use xCode 12.0.1 on MacOS Catalina 10.15.7,
iPad 2018 6-gen iOS 13.7. I retested, looks like the bug still available on iOS 13.4-13.7, but is gone for iOS 14. Good decision for iOS 13 I didn't find.
Steps to reproduce the bug.
I use SwiftUI view (TestCrashIPAD) with List, ForEach and dynamic sections (source code below).
Some static sections are predefined, some dynamic sections appear after fetching from server.
IMPORTANT the bug reproducible only when first appear view! Don't go to another screen or minimize the app!
Just open this view (TestCrashIPAD).
Wait until dynamic sections appers.
As soon as the sections appear, try long-press on the cell with text "r1" or "r2" or ... (screenshot)
Get crash (screenshot)
CRASH
I get crash on AppDelegate with:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
I investigated a little bit, and found: this bug reproducible since iOS 13.4. Also with iOS 13.4 there is a View Modifier onDrag (link). May be it's somehow connected, because in call stack I see:
UIDragInteractionLongPressDriver
UIGestureRecognizer
May be something wrong with dynamic sections array, because I see:
SwiftUI.Sections.rowIDs(forSectionAt: Swift.Int)
SwiftUI.ListCoreDataSource.rowIndex(at: Foundation.IndexPath)
Question
How to fix this issue? How to work around without crash in this case? Please, say any idea.
Source Code
Please have a look the source code:
import SwiftUI
struct TestCrashIPAD: View {
#State var sections = [TestSection]()
var body: some View {
List {
// predefined sections
Section(header: Text("Section predefined")) {
Text("1")
Text("2")
}
Section(header: Text("Section predefined")) {
ForEach(1..<7) {
Text("\($0)")
}
}
// dynamic content
ForEach(sections) { section in
Section(header: Text(section.title)) {
ForEach(section.rows) { row in
HStack {
Text(row.str)
Spacer()
}
}
}
}
}
.listStyle(GroupedListStyle())
.navigationBarTitle("iPad crash with long press")
.onAppear(perform: onAppearAction)
}
func onAppearAction() {
DispatchQueue.global().async {
// fetch some data from the server
sleep(3)
// show data in UI
DispatchQueue.main.async {
self.sections = [TestSection](TestSection.array)
}
}
}
}
struct TestSection: Identifiable {
let id = UUID()
let title: String
let rows: [TestRow]
static var array: [TestSection] {
var result = [TestSection]()
for idx in 0..<50 {
result.append(TestSection(title: "s\(idx)", rows: TestRow.array))
}
return result
}
}
struct TestRow: Identifiable {
let id = UUID()
let str: String
static var array: [TestRow] {
var result = [TestRow]()
for idx in 0..<Int.random(in: 3..<7) {
result.append(TestRow(str: "r\(idx)"))
}
return result
}
}
Looks like the answer is to add .onLongPressGesture { } to your lists that are crashing
(i got this from comments, but this resolved my issues, so seems like an answer. posting as an answer bc not everyone reads comments
I have an iOS app that supports iOS 10 up-to iOS 13 and recently added Catalyst support to it. Through an extension to AppDelegate keyboard short-cuts are supported, and I would like to enable them on iPad as well.
extension AppDelegate {
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
guard builder.system == .main else { return }
// Add menus and shortcuts
}
}
This compiles fine on the Catalyst target, but when building for iOS the following error is given: 'UIMenuBuilder' is only available in iOS 13.0 or newer
The obvious solution is put an availability check in:
#available(iOS 13.0, *)
extension AppDelegate {
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
guard builder.system == .main else { return }
// Add menus and shortcuts
}
}
but then the error changes to Overriding 'buildMenu' must be as available as declaration it overrides.
So for now I excluded the extension from the build on iOS to get a working build, but that means no short-cuts on iPad.
I faced the same exact issue as you. Use:
#if targetEnvironment(macCatalyst)
around your extension instead of the #available suggestion by Xcode.