【问题标题】:Code working in AppDelegate but not in any other class在 AppDelegate 中工作但不在任何其他类中的代码
【发布时间】:2017-12-18 13:00:25
【问题描述】:

我正在使用 socket.io 客户端进行 swift。当我声明并连接套接字并在 AppDelegate 中使用它的命令时,一切正常。但是一旦我将这些东西从 AppDelegate 移动到另一个类(使套接字成为全局变量)并从 AppDelegate 调用该类的函数,套接字错误就开始出现(错误的描述与这个主题真的无关。我有一个关于 Socket.io 问题的讨论) 我想问的问题是这种情况吗?我用过

deinit {
        NSLog("CCNOTIFICATIONS RESOURCES GOT DE INITIALIZED")
       }

在那个文件中,但这永远不会被调用。

据我所知,AppDelegate 是一个委托,当应用的状态发生一些变化(即启动或进入后台/前台)时会调用它。而且在 AppDelegate 中弄乱大量代码也不是一个好习惯。 显然这两个文件的范围没有区别,那么为什么会发生这种情况?

如果我的理解有误,请纠正我。 如何解决这个错误问题?或者至少我可以尝试什么其他方法来解决这个问题? 任何帮助,将不胜感激。

更新: 这是代码: 当我在 AppDelegate 中编写它时:

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
public static var socket = SocketIOClient(socketURL: URL(string: “URL”)!, config: [.log(true), .compress])

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        AppDelegate.socket.connect()
        AppDelegate.socket.on("connect") {data, ack in
           print("Connected successfully")
        }

        AppDelegate.socket.on("book-adventure-provider") {data, ack in 
            print("BOOKING CAME")
            print(data)
       }
        return true
 }

当我将其写入其他文件时:

CCNotifications:

public class CCNotifications : INotifications
{
    public var socket = SocketIOClient(socketURL: URL(string: “URL”)!, config: [.log(true), .compress, .forcePolling(true), .forceNew(true)])


    public func sendBookingRequest(adventureId: String, success: @escaping () -> Void, error: @escaping CErrorCallback) {
        if (ConnectionStatus.isConnected() == false)
        {
            let errorObj = CError()
            errorObj.message = "No internet connection"
            errorObj.code = ClientConstants.connectionErrorCode
            error(errorObj)
        }
        else
        {
            let jwtToken = KeychainWrapper.standard.string(forKey: "jwtToken")
            let data = ["adventure_id": adventureId, "jwt": jwtToken]
            socket.emit("book-adventure", data)

            socket.on("book-adventure-seeker") { data, ack in
                print(data)
            }
        }
    }
}

CuufyClient:

public class CuufyClient : IClient {

    public var notifications: INotifications? = nil

    public static var Notifications: INotifications? { get { return CuufyClient.client?.notifications}}


    //region Actions
    public static func Initialize(completion: ((_ error: CError?) -> Void)?) {

        CuufyClient.client?.notifications = CCNotifications ()

        completion? (nil)
    }
    //endregion
}

最后称它为:

CuufyClient.Notifications?.funcWhichIWannaCall.

注意: 两种方式都有效。但是当我在 CCNotifications 中编写代码并运行它时,有时它会开始给出套接字错误:会话 id 未知,然后一次又一次地连接自己。

更新 2: 日志中套接字错误前的一行我观察到了这个错误:

2017-12-15 15:45:34.133480+0500 TestTarget[5332:230404] TIC Read Status [1:0x60000017f440]: 1:57

搜索此错误后,我了解到在 Xcode 9 中,此错误表明 TCP 连接已关闭。当我在 socket.io 分支上打开这个问题时,专家说:

这个库在底层之上相当高的层次上运行 联网。它依赖 URLSession 或 Starscream 来告诉它 当连接丢失时。

任何人都可以帮助我解决 URLSession 的问题,因为我对 iOS 还很陌生,所以 TCP 会被关闭。

【问题讨论】:

    标签: ios swift socket.io urlsession


    【解决方案1】:

    首先要说,您保持AppDelegate 瘦的方法是个好主意。

    关于deinit:当对象不再存在时,将调用此函数。由于全局变量将“永远”存在 - 只要它们被分配给不同的对象 - 它们只会在程序终止时被清理(而不是:后台模式等)因此,您将永远不会看到 deinit 调用。

    你对生命周期的看法是正确的,如果你做的每一件事都正确应该没有区别 - 我不能在这里判断,因为你没有显示任何关于如何和何时的代码该全局套接字已创建/初始化等。

    关于更新后的问题:很遗憾,我不知道 socket.io 库。但只要看一眼,AppDelegate 和其他版本之间的代码略有不同。这可能是一个时间问题 - 只需检查(并可能修复)一些事情:

    • 什么时候打电话给connect()
    • 您可能需要先设置所有...on()-Handlers连接或调用emit;否则服务器可能在一切设置正确之前做出响应
    • 检查您是否可以集中设置一个...on()-Handlers,而不是在每个sendBookingRequest-call 中设置一个
    • 什么是jwtToken?它是您的应用程序的 API 令牌,还是某种 Seesion 令牌?您何时存储该值,为什么将其存储在钥匙串中?在请求/响应期间它的值可能会发生变化吗?

    【讨论】:

    • 非常感谢您的回答。我已经更新了我的问题并添加了代码。你能看看吗?
    • 感谢您对更新问题的回复。 connect() 是用 CCNotifications 的函数编写的,它在 CuufyClient 的 Initialize 函数上被调用(并且成功连接)...on() 只是一个侦听器。无论它写在哪里,它都会在套接字通知到来时得到通知。 jwtToken 在登录时提供给用户。它在用户登录时存储,之后不会更改。您可以看看问题中的更新 2 吗?我收集了有关该错误的更多信息。也许它会帮助你向我建议一些更接近的解决方案。
    【解决方案2】:

    您不应将套接字事件侦听器放在sendBookingRequest 方法中。 您只需要绑定一次套接字事件监听器。

    socket.on("book-adventure-seeker") { data, ack in
                print(data)
            }
    

    所以,你可以将它放在connect 事件中。

    AppDelegate.socket.on("connect") {data, ack in
               print("Connected successfully")
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-20
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多