Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/

Teste e depuração - Swift SDK

Nesta página

  • Teste
  • Teste usando um domínio padrão
  • Injetando instâncias de domínio
  • Simplifique os testes com projeções de classe
  • Alvos de teste
  • Depuração
  • Depurar usando o realm studio
  • LLDB
  • Solução de problemas
  • Resolver problemas de construção
  • Problemas ao abrir o Realm antes de carregar a interface do usuário
  • Nenhuma propriedade definida para o modelo
  • Alocação incorreta/memória insuficiente disponível
  • O alvo do pacote Swift não pode ser criado dinamicamente

A maneira mais fácil de usar e testar aplicativos apoiados pelo Realm é usar o realm padrão. Para evitar a substituição de dados do aplicativo ou o vazamento de estado entre os testes, defina o realm padrão como um novo arquivo para cada teste.

// A base class which each of your Realm-using tests should inherit from rather
// than directly from XCTestCase
class TestCaseBase: XCTestCase {
override func setUp() {
super.setUp()
// Use an in-memory Realm identified by the name of the current test.
// This ensures that each test can't accidentally access or modify the data
// from other tests or the application itself, and because they're in-memory,
// there's nothing that needs to be cleaned up.
Realm.Configuration.defaultConfiguration.inMemoryIdentifier = self.name
}
}

Outra maneira de testar o código relacionado ao Realm é fazer com que todos os métodos que você gostaria de testar aceitem uma instância do realm como um argumento. Isso permite que você passe em diferentes domínios ao executar o aplicativo e ao testá-lo.

Por exemplo, suponha que seu aplicativo tenha um método para GET um perfil de usuário de uma API JSON. Você deseja testar se o perfil local foi criado corretamente:

// Application Code
func updateUserFromServer() {
let url = URL(string: "http://myapi.example.com/user")
URLSession.shared.dataTask(with: url!) { data, _, _ in
let realm = try! Realm()
createOrUpdateUser(in: realm, with: data!)
}
}
public func createOrUpdateUser(in realm: Realm, with data: Data) {
let object = try! JSONSerialization.jsonObject(with: data) as? [String: String]
try! realm.write {
realm.create(User.self, value: object, update: .modified)
}
}
// Test Code
let realmPath = URL(fileURLWithPath: "...")
func testThatUserIsUpdatedFromServer() {
let config = Realm.Configuration(fileURL: realmPath)
let testRealm = try! Realm(configuration: config)
let jsonData = "{\"email\": \"help@realm.io\"}".data(using: .utf8)!
// In our test, we're passing in the testRealm. This is where we'd
// pass in our "real" realm in the application code above.
createOrUpdateUser(in: testRealm, with: jsonData)
XCTAssertEqual(testRealm.objects(User.self).first!.email, "help@realm.io",
"User was not properly updated from server.")
}

Novidades na versão 10,21,0.

Se quiser trabalhar com um subconjunto das propriedades de um objeto para teste, você pode criar uma projeção de classe. Uma projeção de classe é uma abstração de modelo onde você pode passar, renomear ou excluir propriedades de objeto de domínio. Embora esse recurso simplifique a implementação do modelo de visualização, ele também simplifica os testes com o Realm.

Exemplo

Este exemplo usa os modelos de objetos e a projeção de classes da página Definir e usar projeções de classes.

Neste exemplo, criamos um objeto de domínio usando o modelo de objeto completo. Em seguida, visualizamos a recuperação do objeto como uma projeção de classe, trabalhando com apenas um subconjunto de suas propriedades.

Com esta projeção de classe, não precisamos acessar ou contabilizar propriedades que não precisamos testar.

func testWithProjection() {
let realm = try! Realm()
// Create a Realm object, populate it with values
let jasonBourne = Person(value: ["firstName": "Jason",
"lastName": "Bourne",
"address": [
"city": "Zurich",
"country": "Switzerland"]])
try! realm.write {
realm.add(jasonBourne)
}
// Retrieve all class projections of the given type `PersonProjection`
// and filter for the first class projection where the `firstName` property
// value is "Jason"
let person = realm.objects(PersonProjection.self).first(where: { $0.firstName == "Jason" })!
// Verify that we have the correct PersonProjection
XCTAssert(person.firstName == "Jason")
// See that `homeCity` exists as a projection property
// Although it is not on the object model
XCTAssert(person.homeCity == "Zurich")
// Change a value on the class projection
try! realm.write {
person.firstName = "David"
}
// Verify that the projected property's value has changed
XCTAssert(person.firstName == "David")
}

Não vincule a estrutura do Realm diretamente ao seu alvo de teste. Isso pode fazer com que seus testes falhem com uma mensagem de exceção " O tipo de objeto 'YourObject' não é gerenciado pelo Realm. " Desvincular o Realm do seu alvo de teste deve resolver esse problema.

Compile seus arquivos de classe de modelo em seu aplicativo ou destinos de estrutura; Não adicione-os aos seus destinos de teste de unidade. Caso contrário, essas classes são duplicadas ao testar, o que pode levar a problemas difíceis de depurar.

Exponha todo o código necessário para teste aos seus destinos de teste de unidade. Use o public modificador de acesso ou @testable.

Como você está usando o Realm como uma estrutura dinâmica, você precisará garantir que seu destino de teste de unidade possa encontrar Realm. Adicione o caminho principal para RealmSwift.framework aos "Caminhos de pesquisa da estrutura" do seu teste de unidade.

O Realm Studio permite que você abra e edite domínios locais. É compatível com Mac, Windows e Linux.

A depuração de aplicativos usando a API Swift do Realm deve ser feita por meio do console LLDB.

Embora o script LLDB permita inspecionar o conteúdo de suas variáveis de domínio na interface do usuário do Xcode, isso ainda não funciona para o Swift. Essas variáveis mostrarão dados incorretos. Em vez disso, utilize o comando LLDB po para inspecionar o conteúdo dos dados armazenados em um domínio.

Alguns desenvolvedores enfrentam problemas de criação após a instalação do Realm Swift SDK via CocoaPods ou Cartago. As causas comuns desses problemas incluem:

  • Problemas de instalação:

    • Falha na instalação inicial

    • Usar uma versão não suportada do gerenciador de dependência

  • Problemas com ferramentas de construção:

    • As ferramentas de construção têm caches obsoletos

    • Atualizando versões da ferramenta de construção

  • Fazer alterações na configuração do seu projeto, como:

    • Adicionando um novo alvo

    • Compartilhando dependências entre destinos

Uma correção que muitas vezes limpa esses problemas é excluir dados derivados e limpar a pasta de construção do Xcode.

1

Execute estes comandos no terminal, na raiz do seu projeto:

pod cache clean Realm
pod cache clean RealmSwift
pod deintegrate || rm -rf Pods
pod install --repo-update --verbose
# Assumes the default DerivedData location:
rm -rf ~/Library/Developer/Xcode/DerivedData
2

Com seu projeto aberto no Xcode, vá para o menu suspenso Product (Produto) e selecione Clean Build Folder (Limpar pasta de compilação).

Selecione Produto e, em seguida, Limpe a pasta de compilação.
clique para ampliar
1

Execute estes comandos no terminal, na raiz do seu projeto:

rm -rf Carthage
# Assumes default DerivedData location:
rm -rf ~/Library/Developer/Xcode/DerivedData
carthage update

Importante

Isso atualizará todas as suas dependências gerenciadas por Carthage, não apenas o App Services.

2

Com seu projeto aberto no Xcode, vá para o menu suspenso Product (Produto) e selecione Clean Build Folder (Limpar pasta de compilação).

Selecione Produto e, em seguida, Limpe a pasta de compilação.
clique para ampliar

Você pode abrir um domínio e ver imediatamente falhas com mensagens de erro relacionadas ao fato de as propriedades serem opcionais ou obrigatórias. Problemas com seu modelo de objeto podem causar esses tipos de falhas. Esses erros ocorrem depois que você abre um domínio, mas antes de acessar a interface do usuário.

O Realm tem uma fase de "descoberta de esquema" quando um domínio abre no dispositivo. Neste momento, o Realm examina o esquema de quaisquer objetos que ele gerencia. Você pode especificar que um determinado domínio deve gerenciar somente um subconjunto de objetos em seu aplicativo.

Se você ver erros relacionados às propriedades durante a descoberta do esquema, eles provavelmente se devem a problemas de esquema e não a problemas com dados de um objeto específico. Por exemplo, você pode ver erros de descoberta de esquema se definir uma relação para-um como necessária em vez de opcional.

Para depurar essas falhas, verifique o esquema que você definiu.

Você pode perceber que esses são problemas de descoberta de esquemas porque eles ocorrem antes do carregamento da interface do usuário. Isso significa que nenhum elemento da interface do usuário está tentando usar incorretamente uma propriedade e não há objetos na memória que possam ter dados incorretos. Se você receber erros relacionados às propriedades após o carregamento da interface do usuário, isso provavelmente não é devido a um esquema inválido. Em vez disso, esses erros são provavelmente um resultado de dados incorretos, erroneamente digitados ou ausentes.

O SDK do Realm Swift usa o recurso de reflexão de idioma do Swift para determinar as propriedades em seu modelo no tempo de execução. Se você receber uma falha semelhante à seguinte, confirme se seu projeto não desabilitou os metadados de reflexão:

Terminating app due to uncaught exception 'RLMException', reason: 'No properties are defined for 'ObjectName'.

Se você definir SWIFT_REFLECTION_METADATA_LEVEL = none, o Realm não poderá descobrir filhos de tipos, como propriedades e enumerações. A reflexão será habilitada por padrão se o seu projeto não definir um nível específico para esta configuração.

Em dispositivos iOS ou iPad com pouca memória disponível, ou quando você tiver um aplicativo com uso intensivo de memória que utilize vários realms ou muitas notificações, poderá encontrar o seguinte erro:

libc++abi: terminating due to an uncaught exception of type std::bad_alloc: std::bad_alloc

Esse erro normalmente indica que um recurso não pode ser alocado porque não há memória suficiente disponível.

Se estiver desenvolvendo para iOS 15+ ou iPad 15+, você pode adicionar o Extended Virtual Addressing Entitlement para resolver este problema.

Adicione estas chaves à sua Lista de propriedades e defina os valores para true:

<key>com.apple.developer.kernel.extended-virtual-addressing</key>
<true/>
<key>com.apple.developer.kernel.increased-memory-limit</key>
<true/>

Alterado na versão 10.49.3.

Swift SDK v10.49.3 alterou os detalhes de instalação do pacote com o Swift Package Manager (SPM). Quando você atualiza de uma versão mais antiga do pacote para a v10.49.3 ou mais recente, você pode receber um erro de compilação semelhante a:

Swift package target `Realm` is linked as a static library by `TargetName`
and `Realm`, but cannot be built dynamically because there is a package
product with the same name.

Para solucionar esse erro, desvincule o pacote Realm ou RealmSwift do seu destino de compilação. Você pode fazer isso no Xcode seguindo estas etapas:

  1. Em seu projeto Targets, selecione seu destino de construção.

  2. Acesse a aba Build Phases.

  3. Expanda o elemento Link Binary With Libraries .

  4. Selecione Realm ou RealmSwift e clique no botão Remover itens (-) para remover o binário desnecessário.

    • Se você usa APIs Swift ou Swift e Objective-C, mantenha RealmSwift.

    • Se você usa apenas APIs do Objective-C, mantenha Realm.

Agora seu destino deve construir sem este erro.

Voltar

Simultaneidade do Swift

Próximo

Exploração madeireira