AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-72437

Cheok Yan Cheng's questions

Martin Hope
Cheok Yan Cheng
Asked: 2025-04-14 20:02:05 +0800 CST

Firebase no iOS: avaliando a necessidade de atualização manual de tokens

  • 6

Atualmente, estou usando o seguinte código no meu cliente iOS para determinar se precisamos apresentar uma tela de login:

if Auth.auth().currentUser == nil

Aqui está a lógica da tela de login:

      @objc func handleAppleSignUp() {
          Analytics.logEvent("handleAppleSignUp", parameters: nil)
          
          appleSignUpButton?.stopPulseAnimation()
          
          startSignInWithAppleFlow()
      }

      //
      // https://firebase.google.com/docs/auth/ios/apple
      //
      
      @available(iOS 13, *)
      func startSignInWithAppleFlow() {
        let nonce = randomNonceString()
        currentNonce = nonce
        let appleIDProvider = ASAuthorizationAppleIDProvider()
        let request = appleIDProvider.createRequest()
        request.requestedScopes = [.fullName, .email]
        request.nonce = sha256(nonce)

        let authorizationController = ASAuthorizationController(authorizationRequests: [request])
        authorizationController.delegate = self
        authorizationController.presentationContextProvider = self
        authorizationController.performRequests()
      }
      
      private func randomNonceString(length: Int = 32) -> String {
        precondition(length > 0)
        var randomBytes = [UInt8](repeating: 0, count: length)
        let errorCode = SecRandomCopyBytes(kSecRandomDefault, randomBytes.count, &randomBytes)
        if errorCode != errSecSuccess {
          fatalError(
            "Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)"
          )
        }

        let charset: [Character] =
          Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")

        let nonce = randomBytes.map { byte in
          // Pick a random character from the set, wrapping around if needed.
          charset[Int(byte) % charset.count]
        }

        return String(nonce)
      }

      @available(iOS 13, *)
      private func sha256(_ input: String) -> String {
        let inputData = Data(input.utf8)
        let hashedData = SHA256.hash(data: inputData)
        let hashString = hashedData.compactMap {
          String(format: "%02x", $0)
        }.joined()

        return hashString
      }
  }

  // https://fluffy.es/sign-in-with-apple-tutorial-ios/
  extension LoginViewController:  ASAuthorizationControllerPresentationContextProviding {
      func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
          // Return the window of the current view controller
          return self.view.window!
      }
  }

  extension LoginViewController: ASAuthorizationControllerDelegate {
      func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
          guard let nonce = currentNonce else {
            fatalError("Invalid state: A login callback was received, but no login request was sent.")
          }
          guard let appleIDToken = appleIDCredential.identityToken else {
            print("Unable to fetch identity token")
            return
          }
          guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
            print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
            return
          }
          // Initialize a Firebase credential, including the user's full name.
          let credential = OAuthProvider.appleCredential(withIDToken: idTokenString,
                                                            rawNonce: nonce,
                                                            fullName: appleIDCredential.fullName)
            
          EmulatorUtils.authUseEmulatorIfPossible()
          
          // Sign in with Firebase.
          Auth.auth().signIn(with: credential) { (authResult, error) in
            if let error = error {
              // Error. If error.code == .MissingOrInvalidNonce, make sure
              // you're sending the SHA256-hashed nonce as a hex string with
              // your request to Apple.
              print(error.localizedDescription)
              return
            }
            // User is signed in to Firebase with Apple.
            // ...
              
              Analytics.logEvent("sign_in_success", parameters: nil)
              
              self.delegate?.updateBasedOnLoginStatus()
          }
        }
      }

      func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        // Handle error.
        print("Sign in with Apple errored: \(error)")
      }
  }

Eu estava pensando: será que precisamos atualizar o token de login manualmente? Alguns dos meus usuários relataram que as interações com o Firebase Functions e o Firestore às vezes falham. Em todos os casos, esse problema é resolvido saindo e entrando novamente.

Se eu precisar atualizar o token de login manualmente, alguém pode explicar como e quando fazer isso?

  • 1 respostas
  • 57 Views
Martin Hope
Cheok Yan Cheng
Asked: 2025-04-07 22:47:38 +0800 CST

Comportamento inesperado do ViewThatFits: por que meu ScrollView não está renderizando para conteúdo grande no SwiftUI

  • 5

Quero exibir meu conteúdo como está, centralizado verticalmente, se ele couber na altura da tela.

Só quero envolvê-lo ScrollViewse sua altura exceder a altura da tela.

Estou evitando colocá-lo em um ScrollViewpor padrão, porque conseguir centralização vertical dentro de um ScrollViewpode ser complicado.

Eu tento usar ViewThatFitscom ScrollView.

Eu uso o seguinte código para mostrar conteúdo de altura pequena.


Nenhum ScrollView é renderizado (comportamento correto)

import SwiftUI

struct ContentView: View {
    var largeContent: some View {
        VStack {
            Spacer()
            
            ForEach(1...20, id: \.self) { i in
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundStyle(.tint)
                Text("\(i). Large content!")
                    .font(.largeTitle)
            }
            
            Spacer()
        }
    }
    
    var smallContent: some View {
        VStack {
            Spacer()
            
            ForEach(1...2, id: \.self) { i in
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundStyle(.tint)
                Text("\(i). Small content!")
                    .font(.largeTitle)
            }
            
            Spacer()
        }
    }
    
    var body: some View {
        VStack {
            let smallContent = smallContent
            
            // The top portion dedicated to content
            GeometryReader { x in
                ViewThatFits {
                    // Option 1: Content fits without scrolling.
                    smallContent
                        .background(Color.yellow)
                        .frame(maxHeight: x.size.height)
                        .frame(maxWidth: .infinity)
                    
                    // Option 2: Content is too tall, so wrap it in a ScrollView.
                    ScrollView {
                        smallContent
                            .background(Color.red)
                            .frame(minHeight: x.size.height)
                            .frame(maxWidth: .infinity)
                    }
                }
            }
            
            Text("Button")
                .background(Color.blue)
                .font(.largeTitle)
        }
    }
}

insira a descrição da imagem aqui

Está dentro da minha expectativa porque

  1. Não ScrollViewé renderizado.
  2. O conteúdo é centralizado verticalmente.

Nenhum ScrollView é renderizado (comportamento errado)

import SwiftUI

struct ContentView: View {
    var largeContent: some View {
        VStack {
            Spacer()
            
            ForEach(1...20, id: \.self) { i in
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundStyle(.tint)
                Text("\(i). Large content!")
                    .font(.largeTitle)
            }
            
            Spacer()
        }
    }
    
    var smallContent: some View {
        VStack {
            Spacer()
            
            ForEach(1...2, id: \.self) { i in
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundStyle(.tint)
                Text("\(i). Small content!")
                    .font(.largeTitle)
            }
            
            Spacer()
        }
    }
    
    var body: some View {
        VStack {
            let largeContent = largeContent
            
            // The top portion dedicated to content
            GeometryReader { x in
                ViewThatFits {
                    // Option 1: Content fits without scrolling.
                    largeContent
                        .background(Color.yellow)
                        .frame(maxHeight: x.size.height)
                        .frame(maxWidth: .infinity)
                    
                    // Option 2: Content is too tall, so wrap it in a ScrollView.
                    ScrollView {
                        largeContent
                            .background(Color.red)
                            .frame(minHeight: x.size.height)
                            .frame(maxWidth: .infinity)
                    }
                }
            }
            
            Text("Button")
                .background(Color.blue)
                .font(.largeTitle)
        }
    }
}

#Preview {
    ContentView()
}

insira a descrição da imagem aqui

Agora, alterei para exibir "conteúdo grande". Esperava que a cor vermelha ScrollView fosse renderizada. No entanto, não foi.

Posso saber o que há de errado com meu código? Obrigado.

  • 1 respostas
  • 37 Views
Martin Hope
Cheok Yan Cheng
Asked: 2024-12-15 17:47:03 +0800 CST

Como animar uma substring em um texto?

  • 2

Atualmente, estou usando vários Texts em uma stackview horizontal para obter animação de substring.

insira a descrição da imagem aqui

Como você pode ver na animação acima, o texto

- conversation
- meeting
- lecture

são animados.

Entretanto, há deficiências nessa abordagem.

O tamanho do texto não é consistente entre diferentes blocos de texto. Os Textblocos a seguir têm tamanhos de texto diferentes.

- Transform
- conversation/ meeting/ lecture
- to Quick Note

Alguma ideia de como podemos fazer com que todos os blocos de texto tenham o mesmo tamanho de texto para que pareçam uma frase?

Ou como podemos fazer com que os blocos de texto tenham tamanho de texto constante, mas sejam capazes de realizar quebra de linha para a próxima linha , para que pareçam uma frase?

Atualmente, este é o trecho de código que estou usando.

import SwiftUI

struct ContentView: View {
    var array = ["lecture", "conversation", "meeting"]
    
    @State var currentIndex : Int = 0
    @State var firstString : String = ""

    var body: some View {

        VStack {
            HStack {
                Text("Transform")
                    .lineLimit(1)
                    .minimumScaleFactor(0.5)
                    .font(.title)
                
               Text(firstString)
                    .lineLimit(1)
                    .minimumScaleFactor(0.5)
                    .font(.title)
                    .transition(AnyTransition.opacity.animation(.easeInOut(duration:1.0)))
                    .background(.yellow)
                
                Text("to Quick Note")
                    .lineLimit(1)
                    .minimumScaleFactor(0.5)
                    .font(.title)
            }.padding()
        }
        .animation(.default)
        .onAppear {
            firstString = array[0]
            
            let timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { _ in
                if currentIndex == array.count - 1 {
                    self.firstString = array[0]
                    currentIndex = 0
                }
                else {
                    self.firstString = array[currentIndex+1]
                    currentIndex += 1
                }
            }
        }
    }
}

#Preview {
    ContentView()
}
  • 1 respostas
  • 63 Views
Martin Hope
Cheok Yan Cheng
Asked: 2024-12-07 02:28:54 +0800 CST

Fluxo equivalente GoogleSignInClient.silentSignIn na API do Credential Manager e na API de autorização?

  • 5

Anteriormente, este era nosso fluxo de uso GoogleSignInClientpara interagir com o serviço Google Drive.

Código legado obsoleto

// GoogleSignInClient.silentSignIn() -> GoogleSignInAccount -> Drive object

GoogleSignInClient googleSignInClient = buildGoogleSignInClient();

Task<GoogleSignInAccount> task = googleSignInClient.silentSignIn();

GoogleSignInAccount googleSignInAccount = task.getResult()

Drive drive = getDriveService(googleSignInAccount)

public static GoogleSignInClient buildGoogleSignInClient() {
    GoogleSignInOptions signInOptions =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(GOOGLE_DRIVE_CLIENT_ID)
            .requestEmail()
            .requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
            .build();
    return GoogleSignIn.getClient(WeNoteApplication.instance(), signInOptions);
}

private static Drive getDriveService(GoogleSignInAccount googleSignInAccount) {
    GoogleAccountCredential credential =
        GoogleAccountCredential.usingOAuth2(
            MyApplication.instance(), Collections.singleton(DriveScopes.DRIVE_APPDATA)
        );

    credential.setSelectedAccount(googleSignInAccount.getAccount());
    Drive googleDriveService =
            new Drive.Builder(
                    AndroidHttp.newCompatibleTransport(),
                    new GsonFactory(),
                    credential
            )
            .setApplicationName(APPLICATION_NAME)
            .build();

    return googleDriveService;
}

Agora, estamos tentando cumprir o prazo de descontinuação de GoogleSignInClient- https://android-developers.googleblog.com/2024/09/streamlining-android-authentication-credential-manager-replaces-legacy-apis.html

Baseado em https://stackoverflow.com/a/78605090/72437

Parece que posso pular o uso da API do Credential Manager (autenticação) e ir diretamente para Authorizationa API (autorização)

https://developers.google.com/identity/authorization/android (autorização)

Mas qual é o substituto para o obsoleto googleSignInClient.silentSignIn?

Com isso googleSignInClient.silentSignIn, o usuário pode fazer login apenas uma vez e continuar usando o serviço do Google Drive sem expirar por um longo período de tempo.

Posso saber como podemos obter o equivalente usando AuthorizationAPI?

Obrigado.

  • 1 respostas
  • 33 Views
Martin Hope
Cheok Yan Cheng
Asked: 2024-12-07 02:13:06 +0800 CST

Como chamar o clearCredentialState do CredentialManager do androidx em Java?

  • 5

Referindo-se a este método

https://developer.android.com/reference/androidx/credentials/CredentialManager#clearCredentialState(androidx.credentials.ClearCredentialStateRequest)

Eu queria saber como posso chamá-lo do Java?

Estou usando o seguinte código Java.

Context context = getContext();

// Initialize the CredentialManager instance
CredentialManager credentialManager = CredentialManager.create(context);

// Create a request to clear the credential state
ClearCredentialStateRequest request = new ClearCredentialStateRequest();

credentialManager.clearCredentialState(request);

Mas estou recebendo o seguinte erro do compilador

required: ClearCredentialStateRequest,Continuation<? super Unit>
found:    ClearCredentialStateRequest
reason: actual and formal argument lists differ in length
  • 1 respostas
  • 22 Views
Martin Hope
Cheok Yan Cheng
Asked: 2024-11-11 20:13:30 +0800 CST

UITableViewDiffableDataSource não suporta nil?

  • 5

No exemplo de código a seguir

import UIKit

struct Language: Hashable {
    let name: String
}

enum Section {
    case main
}

class ViewController: UIViewController, UITableViewDelegate {
    var tableView: UITableView!
    private typealias DataSource = UITableViewDiffableDataSource<Section, Language?>

    private var dataSource: DataSource!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set up the table view
        tableView = UITableView(frame: view.bounds)
        view.addSubview(tableView)
        
        // Register a simple cell
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        
        // Set up the data source
        dataSource = DataSource(tableView: tableView) { tableView, indexPath, language in
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            
            // Check if the language is nil and configure the cell accordingly
            if let language = language {
                cell.textLabel?.text = language.name
            } else {
                cell.textLabel?.text = "No Language"
            }
            return cell
        }
        
        // Set up the snapshot with some sample data including nil
        var snapshot = NSDiffableDataSourceSnapshot<Section, Language?>()
        snapshot.appendSections([.main])
        snapshot.appendItems([Language(name: "English"), nil, Language(name: "Spanish"), Language(name: "French")])
        
        // Apply the snapshot to the data source
        dataSource.apply(snapshot, animatingDifferences: true)
        
        tableView.delegate = self
    }
}

Estou recebendo erro de tempo de execução

Could not cast value of type 'NSNull' (0x1ec78e900) to 'xxx.Language' (0x1008e0468).

Não é UITableViewDiffableDataSourcecompatível nil? Não consigo encontrar https://developer.apple.com/documentation/uikit/uitableviewdiffabledatasource falando sobre essa limitação.

Obrigado.

swift
  • 1 respostas
  • 31 Views
Martin Hope
Cheok Yan Cheng
Asked: 2024-11-01 23:44:15 +0800 CST

Compreendendo o Firestore addSnapshotListener: ele retorna todos os documentos correspondentes ou apenas novas inserções?

  • 5

Se um documento com status 'sucesso' for inserido, o addSnapshotListenerretorno de chamada retornará todos os documentos com status 'sucesso' (novos e existentes) ou apenas o documento recém-inserido com status 'sucesso'?

private func monitorNoteChanges() {
    guard let uid = Auth.auth().currentUser?.uid else { return }

    self.stopMonitoring()
    
    let db = FirestoreUtils.firestore()
    
    // Reference to the notes subcollection for the specific user
    let notesRef = db.collection("users").document(uid).collection("notes")
    
    let statusValues = [
        Status.success.rawValue
    ]
    
    // Query to listen for changes to documents where status matches the specified value
    let query = notesRef.whereField("status", in: statusValues).whereField("trashed", isEqualTo: false)
    
    // Attach a listener and store the ListenerRegistration
    let listener = query.addSnapshotListener { [weak self] (querySnapshot, error) in
        guard let self = self else { return }
        
        guard let documents = querySnapshot?.documents else {
            print("No documents or an error occurred: \(error?.localizedDescription ?? "Unknown error")")
            return
        }
        
        // TODO: documents
    }
    
    self.listener = listener
}

Inicialmente, pensei que apenas documentos recém-inseridos seriam retornados pelo ouvinte.

No entanto, notei que sempre que um novo documento é inserido, tanto o novo documento quanto todos os documentos correspondentes existentes são retornados.

Esse comportamento é correto e garantido?

  • 1 respostas
  • 26 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve