I'm kind of new to Ios development and still figuring out Xcode.
I have downloaded Xcode 12 beta 3 and I am using SwiftUI.
I was using Xcode 11 and when I wrote print("something") everything went well.
after upgrading to 12 beta 3 no print statement is working for me and errors are not shown as well.
I am trying to understand if it something I did wrong in Xcode settings or maybe a bug.
Any help or suggestion will do.
btw, the network request doesn't get to the server. I believe it fails before. the server is working properly. Maybe this info can assist someone.
Thanks a lot in advance!
code sample:
import Foundation
protocol TodosNetworkServiceProtocol {
func fetchTodos(includingCompleted: Bool) -> [Todo]
func update(todo: Todo)
func add(todo: Todo)
func toggleIsCompleted(for todo: Todo)
}
// final class means it cant be inharited
final class TodosNetworkService: TodosNetworkServiceProtocol {
func fetchTodos(includingCompleted: Bool) -> [Todo] {
guard let todosUrl = URL(string: "http://localhost:5000/todos") else { return [] }
URLSession.shared.dataTask(with: todosUrl) { (data, response, error) in
// Here it gets into the if but print nothing.
if error != nil { print(error) }
guard let data = data else { return }
do {
let response = try JSONDecoder().decode([Todo].self, from: data)
} catch let err {
print(err)
return
}
}.resume()
return []
}
func update(todo: Todo) {
print("updating todo")
}
func add(todo: Todo) {
print("adding todo")
}
func toggleIsCompleted(for todo: Todo) {
print("toggeling todo")
}
}
First enable the debug window to open when ever you run a new build. saves you having to go view > debug area > ... or use the keyboard shortcuts.
Then when the debug area opens it hits a breakpoint. Unselect the breakpoint and the debug area will output your print statements
Related
Situation
Hi there,
I am developing an iOS app and while building my project I run into the following error message:
Error: Trace/BPT trap: 5
I didn't find anything online to fix this problem, so I wanted to know, if anyone here might be able to help.
I also had issues with Cocoapods and my Silicon Mac, so I want to list my steps I've tried fixing:
Setup
M1 MacBook Pro, macOS 11.1
XCode Version 12.4
Cocoapods with Pods for Firebase Swift, Auth, Firestore and Storage
Steps I tried fixing
cmd + shift + k for cleaning the build folder
closing XCode and opening Terminal using Rosetta
delete ~/Library/Developer/Xcode/Derived Data - Folder
pod deintegrate in project directory
delete Podfile.lock, app.xcworkspace, Pods directory
pod install
in app and pods projects build settings setting Excluded Architectures for any iOS Simulator SDK to arm64
setting Build Active Architecture Only to yes
convert Pods Project to Swift 5
build Pods Project
build app project
And then the following error occurs:
Log
Log enty from Merge swiftmodule (x86_64):
https://pastebin.com/MiSKGxB7
(Log way to long, exceeds character limit).
Code
As the error somewhere tells, it occured while trying to serialize the class BaseViewModel, here's the code from the Base.swift file I wrote containing that class:
import SwiftUI
import Firebase
import FirebaseFirestore
import Combine
protocol BaseModel: Identifiable, Codable {
var id: String? { get set }
var collection: String { get }
init()
}
class BaseViewModel<T: BaseModel>: ObservableObject, Identifiable, Equatable {
#Published var model: T
var id: String {
didSet {
self.model.id = id
}
}
var cancellables = [AnyCancellable]()
private var db = Firestore.firestore()
required init(){
let model = T.init()
self.model = model
self.id = model.id ?? UUID().uuidString
}
required init(id: String) {
var model = T.init()
model.id = id
self.model = model
self.id = id
}
init(model: T) {
self.model = model
self.id = model.id ?? UUID().uuidString
}
static func ==(lhs: BaseViewModel<T>, rhs: BaseViewModel<T>) -> Bool {
lhs.model.id == rhs.model.id
}
func load(completion: #escaping (Bool) -> Void = {finished in}){
if let id = model.id {
self.id = id
db.collection(model.collection).document(id).getDocument { docSnapshot, error in
guard let doc = docSnapshot else {
print("Error fetching document: \(error!)")
return
}
do {
guard let data = try doc.data(as: T.self) else {
print("Document empty \(type(of: self.model)) with id \(id)")
return
}
self.model = data
self.loadSubData {finished in
if finished{
completion(true)
}
}
} catch {
print(error.localizedDescription)
}
}
}
}
func loadSubData(completion: #escaping(Bool) -> Void = {finished in}) {
fatalError("Must be overridden!")
}
func loadDataByIDs<T, S>(from list: [String], appender: #escaping (T) -> Void) where T: BaseViewModel<S>, S: BaseModel {
for id in list {
let viewModel = T.init(id: id)
viewModel.load{finished in
if finished {
appender(viewModel)
}
}
}
}
func save(){
do {
let _ = try db.collection(model.collection).addDocument(from: model)
} catch {
print(error)
}
}
func update(){
if let id = model.id {
do {
try db.collection(model.collection).document(id).setData(from: model)
} catch {
print(error.localizedDescription)
}
}
}
func delete(){
if let id = model.id {
db.collection(model.collection).document(id).delete() { error in
if let error = error {
print(error.localizedDescription)
}
}
}
}
}
I had the same problem, I am solved it after I updated Quick/Nimble.
I guess some pod project with x86 files meed to update to support M1
Well for the record, anybody who is experiencing these odd bugs on M1 must read exactly inside the excode compilation error.
If they are saying a specific class it means xcode can't compile your code and you should just remove the code and try to compile line by line.
I know that's very strange, looks like programming PHP and refreshing a webpage but I'm sure this type of bug can be related to the platform migration.
In my situation, I had a class that was OK, I started refactoring and instead of xcode showing me the compilation errors, it gave this cryptic BPT5, at reading exactly the description inside of the IDE I could find that my class was the root cause.
Just remove the code all over you changed and try to compile it again...
Sorry for the late update on that. But in my case it was either CocoaPods in general or the Firebase Pods, which were not compatible with Apple Silicon at that time.
I was just using Swift Package Manager and with that, it worked.
I do not know though, if the problem still exists, because I didn't build another app on the M1 MacBook.
I run into this issue after I accidently extract a view as variable without awareness. You shall check your recently committed code to figure it out.
I have a command line app that does the following:
downloads an RSS feed with torrent links
stores it in a sqlite database and tags them as "added" or "ignored"
connects to a transmission server (in my local network)
loads items from sqlite marked as "added" and adds to transmission server
The above works fine in debug mode. However, when I build for release and try to run directly or from launchd, it always times out. The most relevant code is in main.swift which goes below.
private func getTransmissionClient() -> Transmission? {
let client = Transmission(
baseURL: serverConfig.server,
username: serverConfig.username,
password: serverConfig.password)
var cancellables = Set<AnyCancellable>()
let group = DispatchGroup()
group.enter()
print("[INFO] Connecting to client")
client.request(.rpcVersion)
.sink(
receiveCompletion: { _ in group.leave() },
receiveValue: { rpcVersion in
print("[INFO]: Successfully Connected! RPC Version: \(rpcVersion)")
})
.store(in: &cancellables)
let wallTimeout = DispatchWallTime.now() +
DispatchTimeInterval.seconds(serverConfig.secondsTimeout ?? 15)
let res = group.wait(wallTimeout: wallTimeout)
if res == DispatchTimeoutResult.success {
return client
} else {
return nil
}
}
public func updateTransmission() throws {
print("[INFO] [\(Date())] Starting Transmission Update")
let clientOpt = getTransmissionClient()
guard let client = clientOpt else {
print("[ERROR] Failed to connect to transmission client")
exit(1)
}
var cancellables = Set<AnyCancellable>()
let items = try store.getPendingDownload()
print("[INFO] [\(Date())] Adding \(items.count) new items to transmission")
let group = DispatchGroup()
for item in items {
let linkComponents = "\(item.link)".components(separatedBy: "&")
assert(linkComponents.count > 0, "Link seems wrong")
group.enter()
client.request(.add(url: item.link))
.sink(receiveCompletion: { completion in
if case let .failure(error) = completion {
print("[Failure] \(item.title)")
print("[Failure] Details: \(error)")
}
group.leave()
}, receiveValue: { _ in
print("[Success] \(item.title)")
do {
try self.store.update(item: item, with: .downloaded)
} catch {
print("[Error] Couldn't save new status to DB")
}
})
.store(in: &cancellables)
}
let wallTimeout = DispatchWallTime.now() +
DispatchTimeInterval.seconds(serverConfig.secondsTimeout ?? 15)
let res = group.wait(wallTimeout: wallTimeout)
if res == DispatchTimeoutResult.success {
print("Tasks successfully submitted")
} else {
print("Timed out")
exit(1)
}
}
Oddly enough, the code seemed to work fine before I added the database. The DispatchGroup was already there, as well as the Transmission-Swift client. I guess something that I did is being "optimized away" by the compiler? This is just speculation though after seeing some other questions on StackOverflow, but I am still not clear on it.
I am using macOS 10.15 and Swift 5.2.2.
Full code available in github (link to specific commit that has the bug)
I asked for help on Swift Forums at https://forums.swift.org/t/not-connecting-to-rpc-server-in-release-mode-but-works-fine-in-debug-mode/36251 and here is the gist of it:
Debug vs Release bugs are common in the Apple ecosystem.
One common reason for the above: the compiler has much more aggressive retain and release patterns in release mode.
My problem was exactly that: a certain class was being disposed of earlier than it should and it was exactly the cancellable for the subscription, so my server requests were being cancelled in the middle.
This commit fixes it and it basically does the following:
diff --git a/Sources/TorrentRSS/TorrentRSS.swift b/Sources/TorrentRSS/TorrentRSS.swift
index 17e1a6b..0b80cd5 100644
--- a/Sources/TorrentRSS/TorrentRSS.swift
+++ b/Sources/TorrentRSS/TorrentRSS.swift
## -63,6 +63,10 ## public struct TorrentRSS {
DispatchTimeInterval.seconds(serverConfig.secondsTimeout ?? 15)
let res = group.wait(wallTimeout: wallTimeout)
+ for cancellable in cancellables {
+ cancellable.cancel()
+ }
+
if res == DispatchTimeoutResult.success {
return client
} else {
## -117,6 +121,11 ## public struct TorrentRSS {
let wallTimeout = DispatchWallTime.now() +
DispatchTimeInterval.seconds(serverConfig.secondsTimeout ?? 15)
let res = group.wait(wallTimeout: wallTimeout)
+
+ for cancellable in cancellables {
+ cancellable.cancel()
+ }
+
if res == DispatchTimeoutResult.success {
print("Tasks successfully submitted")
} else {
Calling cancellable explicitly avoids the object being disposed of before it should. That specific location is where I meant to dispose of the object, not any sooner.
In Xcode 11 beta 5 or 6 my existing code that relied on URLSession.DataTaskPublisher stopped working. It seems like DataTaskPublisher is never publishing any values but I can't work out why.
I've tried with .sink and .handleEvents as subscribers. I've tested .sink with a Just publisher and confirmed it receives a value there.
I've also tried both giving the DataTaskPublisher a URL and giving it a URLRequest. I've tried a request to an API including an authorization header, as well as basic requests to google.com and apple.com. I've tried using URLSession.shared and creating a new instance of URLSession. I've also tried with and without map and decode operators.
I've used XCTest expectations to confirm that the test times out every single time, even if I give it a 4-minute timeout.
I just made a new example project and replicated the problem with the following code in the root view controller:
override func viewDidLoad() {
super.viewDidLoad()
print("view did load")
URLSession.shared.dataTaskPublisher(for: URL(string: "http://apple.com")!)
.handleEvents(receiveSubscription: { (sub) in
print(sub)
}, receiveOutput: { (response) in
print(response)
}, receiveCompletion: { (completion) in
print(completion)
}, receiveCancel: {
print("cancel")
}, receiveRequest: { (demand) in
print(demand)
})
}
The project prints "view did load" but nothing else ever prints. Any ideas about where I'm going wrong here? Thanks!
I think that there are two problems with your code, firstly you only have a publisher (handleEvent returns a publisher) and secondly that publisher goes out of scope and disappears. This works although it isn't exactly elegant.
import Combine
import SwiftUI
var pub: AnyPublisher<(data: Data, response: URLResponse), URLError>? = nil
var sub: Cancellable? = nil
var data: Data? = nil
var response: URLResponse? = nil
func combineTest() {
guard let url = URL(string: "https://apple.com") else {
return
}
pub = URLSession.shared.dataTaskPublisher(for: url)
.print("Test")
.eraseToAnyPublisher()
sub = pub?.sink(
receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
fatalError(error.localizedDescription)
}
},
receiveValue: { data = $0.data; response = $0.response }
)
}
struct ContentView: View {
var body: some View {
Button(
action: { combineTest() },
label: { Text("Do It").font(.largeTitle) }
)
}
}
I did it in SwiftUI so that I would have less to worry about and I used 3 variables so that I could follow better. You need to use the 2 parameter sink as the publisher's error isn't Never. Finally the print() is just for test and works really well.
I recently updated my parse project to swift 3 today and to my dismay not a single saveInBackgroundWithBlock, getDataInBackground, findObjectsInBackGround etc worked. -______- Here is an example of a section that does not work:
newCart.saveInBackground { (saved:Bool, error:NSError?) -> Void in
if saved {
print("saved worked")
} else {
print(error)
}
}
So after some quick research, I figured out that in a nutshell, Apple wanted to omit anything that was deemed unnecessary from the swift syntax. This means something as petty as NS in NSError is not ok with the new swift 3. So in my parse save function above or in any other getData or findObjects, the only thing you need to do to get Xcode to chill out is change NSError in newCart.saveInBackground { (saved:Bool, error:NSError?) -> Void in to Error. so that the end result would look like:
let newCart = PFObject(className: "Cart")
newCart.saveInBackground { (saved:Bool, error:Error?) -> Void in
if saved {
print("saved worked")
} else {
print(error)
}
}
I'am using Swift 1.2 with ReactiveCocoa 3.0, SwiftyJSON 2.2.1 and Alamofire 1.3.1. I am building a reactive network manager.
Why is the following not working?
func sendRequest(request: ApiRequest) -> SignalProducer<JSON, NSError> {
return SignalProducer { sink, disposable in
alamofireManager.request(request.method, request.url, parameters:request.parameters, encoding: .JSON).responseJSON
{ (request, response, data, error) in
if let error = error {
// sendError(sink, error)
} else {
NSLog("Successful network request")
// sendNext(observer, JSON(data!))
// sendCompleted(sink)
}
}
}
}
sendError, sendNext and sendCompleted are not compiling. When they are uncommented the compiler says:
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1
When debugging I see that sink and disposable are not visible inside the Alamofire closure. Strangest thing: This used to work some hours ago.
Wow, after hours of searching I found the solution.
It seems the outer closure does not persist variables (here: sink and disposable) if not assigned to a variable explicitly. I did this with
let sink = sink
The following works:
func sendRequest(request: ApiRequest) -> SignalProducer<JSON, NSError> {
return SignalProducer { sink, disposable in
let sink = sink
self.alamofireManager.request(request.method, request.url, parameters:request.parameters, encoding: .JSON).responseJSON
{ (request, response, data, error) in
if let error = error {
sendError(sink, error)
} else {
sendNext(sink, JSON(data!))
sendCompleted(sink)
}
}
}
}
Maybe anyone can explain this a bit more general? I thought the outer closure with its parameters will be available inside the inner closure automatically. Might this be a bug in the swift compiler?