ios - reorder items in uitableview and apply changes to sqlite database - ios

i'm trying to reorder a table view - have set up the canMoveRowAtIndexPath and moveRowAtIndexPath so that I can drag the cells around when i'm in editing mode, but I need to basically mirror these changes in an sqlite database that I have. i have a column called "orderid" which i'm using to keep track of the order of the cells. My approach has been to basically set the cell being moved to orderid=9999, then add or subtract 1 from from the orderid of the rest of the affected cells, then set the new cell to its destination orderid. i think it's likely to be an sql error but i can't figure it out. if anyone has any advice it would be much appreciated.
these are my methods:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
long source = (long)sourceIndexPath.row;
long dest = (long)destinationIndexPath.row;
source++;
dest++;
//reorder in db
NSString *sql;
if (source>dest) {
sql = [NSString stringWithFormat:#"UPDATE entries SET orderid=9999 where orderid=%ld; update entries set orderid = orderid + 1 where orderid<%ld AND orderid>=%ld update entries set orderid=%ld where orderid=9999", source, source,dest, dest];
} else if (source<dest){
sql = [NSString stringWithFormat:#"UPDATE entries SET orderid=9999 where orderid=%ld; update entries set orderid = orderid - 1 where orderid BETWEEN orderid>%ld AND orderid<=%ld; update entries set orderid=%ld where orderid=9999", source, source, dest, dest];
}
NSLog(#"%#", sql);
char *err;
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) !=SQLITE_OK) {
sqlite3_close(db);
NSLog(#"could not reorder");
} else {
NSLog(#"rows reordered");
}
}

I am using pageOrder to create an order in my pages table. This is table :
.s pages
CREATE TABLE pages (
uuid INTEGER PRIMARY KEY,
name TEXT,
pageOrder INTEGER DEFAULT 0
);
Here is the code :
int fromRow = [sourceIndexPath row];
int toRow = [destinationIndexPath row];
if (toRow != fromRow) {
FMDatabase* db = [FMDatabase databaseWithPath:[appDelegate dbPath]];
[db open];
[db executeUpdate:#"UPDATE pages SET pageOrder = -? WHERE pageOrder = ?",
[NSNumber numberWithInt:toRow + 1],
[NSNumber numberWithInt:fromRow + 1]];
if (toRow < fromRow) {
[db executeUpdate:#"UPDATE pages SET pageOrder = pageOrder + 1 WHERE pageOrder > ? AND pageOrder <= ?",
[NSNumber numberWithInt:toRow],
[NSNumber numberWithInt:fromRow]];
} else {
[db executeUpdate:#"UPDATE pages SET pageOrder = pageOrder - 1 WHERE pageOrder > ? AND pageOrder <= ?",
[NSNumber numberWithInt:fromRow],
[NSNumber numberWithInt:toRow + 1]];
}
[db executeUpdate:#"UPDATE pages SET pageOrder = abs(pageOrder) WHERE pageOrder < 0"];
[db close];
}
Should be working,
Cheers,
Eddy

One possibility may be if the numberOfRows in your tableView does not match the number of entries in your database, for example: if you have an ‘Add new row...’ cell on the bottom of the tableView, then you may run into trouble, like I have in the past. My trouble was that the tableView:moveRowAtIndexPath:toIndexPath was returning the wrong sourceIndexPath. Two solutions both solved the problem. First solution: Call [tableview reloadData] in the tableView:moveRowAtIndexPath:toIndexPath:, you may lose the row animation but you will keep the functionality and sourceIndexPath/destinationIndexPath will be updated. Second solution: Don’t use an ‘Add new row...’ cell on the bottom and find alternate solution to add. Good luck!

I would suggest using float order_id. And when user reorders item, get order_id of previous and next item, get their mean (float) and save to DB. This way, you need to update only reordered item.

This Works fine with me!
- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)targetIndexPath{
// Define las variables a utilizar: IDorigen hace referencia al ID que tiene la fila antes de moverse e IDDestino hace referencia al ID que va a tener la fila luego de moverse
int IDorigen = (int)[sourceIndexPath row]+1;
int IDdestino = (int)[targetIndexPath row]+1;
int diferencia;
// Define la variable de consulta sobre la base de datos
NSString *consulta;
// Si el IDorigen es menor al IDdestino (es decir, mueve una fila hacia abajo)
if (IDorigen < IDdestino)
{
// Obtiene la diferencia para saber cuantas filas hay entre IDdestino e IDOrigen
diferencia = IDdestino - IDorigen;
// Hace un FOR desde cero hasta diferencia, y a cada fila que encuentra le pone el ID=9000+i. Esto se hace para mandar las filas invoulucradas en el movimientohacia abajo de todo y evitar conflictos de ID
for (int i=0;i<diferencia;i++){
// Define la consulta
consulta = [NSString stringWithFormat:#"update homeTabla set ID=%d where ID=%d", 9000+i,IDorigen+1+i];
// Ejecuta la consulta
[self.dbTouchMeCIS executeQuery:consulta];
}
// Cuando finaliza el FOR, le asigna a la fila que se está moviendo, el IDdestino deseado definiendo la consulta
consulta = [NSString stringWithFormat:#"update homeTabla set ID=%d where ID=%d", IDdestino,IDorigen];
// Ejecuta la consulta
[self.dbTouchMeCIS executeQuery:consulta];
// Hace un FOR para asignarle el valor que corresponde a aquellas filas que se le asigno el ID=9000+i
for (int i=0;i<diferencia;i++){
// Define la consulta
consulta = [NSString stringWithFormat:#"update homeTabla set ID=%d where ID=%d",IDorigen+i,9000+i];
// Ejecuta la consulta
[self.dbTouchMeCIS executeQuery:consulta];
}
// Si el IDorigen es mayor al IDdestino (es decir, mueve una fila hacia arriba)
}else if (IDorigen > IDdestino){
// Obtiene la diferencia para saber cuantas filas hay entre IDdestino e IDOrigen
diferencia = IDorigen - IDdestino;
// Hace un FOR desde cero hasta diferencia, y a cada fila que encuentra le pone el ID=9000+i. Esto se hace para mandar las filas involucradas en el movimiento hacia abajo de todo y evitar conflictos de ID
for (int i=0;i<diferencia;i++){
// Define la consulta
consulta = [NSString stringWithFormat:#"update homeTabla set ID=%d where ID=%d", 9000+i,IDdestino+i];
// Ejecuta la consulta
[self.dbTouchMeCIS executeQuery:consulta];
}
// Cuando finaliza el FOR, le asigna a la fila que se está moviendo, el IDdestino deseado definiendo la consulta
consulta = [NSString stringWithFormat:#"update homeTabla set ID=%d where ID=%d", IDdestino,IDorigen];
// Ejecuta la consulta
[self.dbTouchMeCIS executeQuery:consulta];
// Hace un FOR para asignarle el valor que corresponde a aquellas filas que se le asigno el ID=9000+i
for (int i=0;i<diferencia;i++){
// Define la consulta
consulta = [NSString stringWithFormat:#"update homeTabla set ID=%d where ID=%d",IDdestino+1+i,9000+i];
// Ejecuta la consulta
[self.dbTouchMeCIS executeQuery:consulta];
}
}
// Recarga la base de datos en la tabla una vez finalizado el movimiento
[self recargarDatos];
}

Related

Google Sheet merged cells create space

I got a sheet with merged cells and in those merged cells, a script write its results.
When I copy this result in the merged cells, it gave me multiple spaces at the end.
Like : Result #1________ (« _ » represent invisible space)
When I put the same result in a normal cell (not merged), it doesn’t put any space at the end.
Result #1
I tried multiple cell format (Center aligned, left aligned, etc.) but nothing changed.
Do you have any idea why ?
Thanks !
EDIT : add script
Script
function Devise() {
const sheetName = "Missions";
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var Devise = "";
var NombreMission = "";
var NomOperateurs = "";
if(sheet.getRange("H2").getValue()=="") { // Si la mission 7 est vide
NombreMission = 6; // On compte seulement 6 missions
} else {
NombreMission = 7; // Sinon on compte 7 missions
}
for (i = 1; i < NombreMission+1; i++) { // Boucle FOR pour NombreMission missions
if(sheet.getRange(2,i+1).getValue()=="") { continue; } // Si la mission est vide, on la passe
Devise = Devise + i + "/";
l = 0; // Variable pour indiquer "Rien" si personne à placer dans la mission
NomOperateurs = ""; // Reset les noms pour la mission d'après
for (j = 1; j < 27+1; j++) { // Boucle FOR pour tous les opérateurs
if(sheet.getRange(j+2,i+1).getFontWeight() == 'bold') { // Vérifie si la case est en gras
/*if(i!=NombreMission) { // Tant qu'il ne s'agit pas de la dernière mission ...
Devise = Devise + sheet.getRange(j+2,1).getValue() + " "; // ... on affiche les opérateurs
}*/
NomOperateurs = NomOperateurs + sheet.getRange(j+2,1).getValue() + " ";
l = l + 1; // On compte les opérateurs
}
} // Fin Boucle FOR opérateurs
if (l==24) { // S'il y a tous les operateurs sur une mission...
Devise = Devise + "ALL OPs! " // ... On affiche "All Op!"
} else if (i==NombreMission && l!=0) { // Sinon s'il s'agit de la dernière mission et qu'il reste des opérateurs à placer...
Devise = Devise + "Autres + Epic "; // ... On indique qu'il s'agit du reste et des épiques
} else if (l==0) { // Sinon s'il n'y a aucun opérateurs à placer...
Devise = Devise + "RIEN " // ... On indique "RIEN"
} else { // Sinon ...
Devise = Devise + NomOperateurs; // ... On affiche les opérateurs
}
} // FIN BOUCLE FOR NombreMission
if(NombreMission==6 && Devise!="") { Devise = Devise + "7/!NOTHING!";}
sheet.getRange("K13").setValue(Devise);
}
Your problem is related to the data you copied and the way that you copied it as pasting text in merged cells doesn't create any new lines.
Also, an important thing to keep in mind is that CTRL+ENTER creates the mentioned space also known as a line break.
So, for example, if this cell contains the text Text + line break:
And the text from the above cell is copied and pasted into a merged cell it will look like this - which is the same outcome as the one that you have mentioned:
But if you paste the same text to a simple cell, it will look like this:
This is essentially because the line break will signify the start of a new cell.
For example, this cell contains this text with line breaks:
After the text is copied and pasted into a different cell, this is how it will actually be pasted as:
In order to solve your issue, I suggest you to copy only the text needed and if possible to avoid using any line breaks.
Reference
Edit and Format a Spreadsheet.
Encountering the same issue.
I have a merged cell with text. If I select the cell and paste it into notepad, It includes quite a lot of white space.
I've checked and if the merged cell spans two rows, the white space includes a line break.
If the merged cell spans one row but two columns, the white space does not include a line break.
If I have a single cell and have it take its value from the mered cell "=A1", the text does not include the white space.
So the addition of the whitespace is definitely the result of having a merged cell.

BLE write characteristic ios

It's me again
I got connection between a mini thermal printer and a iOS device, everything is fine except for the number of letters that it prints.
If a want to print a long string it just print a few of them.And the worst is this.
For example if i want to print this "aaaaa1aaaa1" and this "bbbbb2bbbb2"
the result is
"aaaaa1" "aaaa1b" "bbbb2b" "bbbb2" (each block is separated)
this is the code for the print button
#IBAction func btnImprimironClick(_ sender: Any) {
let mensaje = "-----Guillermo Celi (CREO-SUMA) dijo que el primer mandatario está dentro del plazo para remitir un alcance al veto parcial, y pueda “objetar la creación de los cuerpos de seguridad para la custodia de burócratas”. Explicó que su bancada está en contra de ese capítulo del proyecto porque es inconstitucional, y que esa tarea le corresponde a las Fuerzas Armadas y la Policía Nacional. La comisión de Soberanía y Asuntos Internacionales, presidida por Doris Soliz (AP), se allanó al veto parcial del Ejecutivo. Ella señaló que lo único que cabe es acoger el informe pese al pedido de la oposición."
var datos = mensaje.data(using: .utf8)!
self.printer.writeValue(datos , for: characteristic1, type: CBCharacteristicWriteType.withoutResponse)
Please help me with this, could be something wrong whit the code or the utf8
Thanks.
For some reason it's about the coding format, first I use the utf8 because its a standard but I change to macOSRoman and work perfectly.
static func printText(text: String)
{
let text = "Some long paragraph in spanish version."
let byteArray = text.data(using:String.Encoding.macOSRoman)
self.printer.writeValue(byteArray! , for: characteristic1, type: CBCharacteristicWriteType.withoutResponse)
}

List of Authorisation errors with Firebase login

What I need is a complete list of FirebaseAuthentication codes for all the different login errors and also a list of all those errors. So far I have found some by trial and error but can't take the risk I have missed some.
I am using the Firebase simple login to log in with email/password, facebook, twitter and also anonymous logins. Obviously with this many login methods there are lots of ways the user can fail to login correctly (incorrect email format, didn't enter a password etc). Currently I am using this code:
... authenticateWithDictionary method
completion:^(NSError * error, id<PUser> user) {
if (!error) {
[self loginButtonPressed:Nil];
}
else {
[UIView alertWithTitle:bErrorTitle withError:error];
}
The only issue with this is I end my getting errors raised which read like this:
**(Error Code: EMAIL_TAKEN) The specified email address is already in use.**
This is fine to let me know what has gone wrong in testing but once the app goes live I will want individual messages to
a) look tidier
b) let the user know why they have got this error
So far through trial and error I have figured out the following:
error code
-5 INVALID EMAIL - empty or incorrect format
-6 INVALID PASSWORD
-9 EMAIL TAKEN
Once I have a complete list I am going to use a switch statement to get them all being dealt with correctly
Does anyone know the comprehensive list of error codes and errors so that I can take them all into account without having to think through all the options which might mean I miss one
You can find all firebase auth errors codes and explanations under FIRAuthErrorCode enum in FirebaseAuth.framework
/*
Indicates a validation error with the custom token.
*/
FIRAuthErrorCodeInvalidCustomToken = 17000,
/*
Indicates the service account and the API key belong to different projects.
*/
FIRAuthErrorCodeCustomTokenMismatch = 17002,
/*
Indicates the IDP token or requestUri is invalid.
*/
FIRAuthErrorCodeInvalidCredential = 17004,
/*
Indicates the user's account is disabled on the server.
*/
FIRAuthErrorCodeUserDisabled = 17005,
/*
Indicates the administrator disabled sign in with the specified identity provider.
*/
FIRAuthErrorCodeOperationNotAllowed = 17006,
/*
Indicates the email used to attempt a sign up is already in use.
*/
FIRAuthErrorCodeEmailAlreadyInUse = 17007,
/*
Indicates the email is invalid.
*/
FIRAuthErrorCodeInvalidEmail = 17008,
/*
Indicates the user attempted sign in with a wrong password.
*/
FIRAuthErrorCodeWrongPassword = 17009,
/*
Indicates that too many requests were made to a server method.
*/
FIRAuthErrorCodeTooManyRequests = 17010,
/*
Indicates the user account was not found.
*/
FIRAuthErrorCodeUserNotFound = 17011,
/*
Indicates account linking is required.
*/
FIRAuthErrorCodeAccountExistsWithDifferentCredential = 17012,
/*
Same enum as #c FIRAuthErrorCodeAccountExistsWithDifferentCredential ,
but with incorrect spelling. Only exists for backwards compatiblity.
*/
FIRAuthErrrorCodeAccountExistsWithDifferentCredential = 17012,
/*
Indicates the user has attemped to change email or password more than 5 minutes after
signing in.
*/
FIRAuthErrorCodeRequiresRecentLogin = 17014,
/*
Indicates an attempt to link a provider to which the account is already linked.
*/
FIRAuthErrorCodeProviderAlreadyLinked = 17015,
/*
Indicates an attempt to unlink a provider that is not linked.
*/
FIRAuthErrorCodeNoSuchProvider = 17016,
/*
Indicates user's saved auth credential is invalid, the user needs to sign in again.
*/
FIRAuthErrorCodeInvalidUserToken = 17017,
/*
Indicates a network error occurred (such as a timeout, interrupted connection, or
unreachable host). These types of errors are often recoverable with a retry. The #c
NSUnderlyingError field in the #c NSError.userInfo dictionary will contain the error
encountered.
*/
FIRAuthErrorCodeNetworkError = 17020,
/*
Indicates the saved token has expired, for example, the user may have changed account
password on another device. The user needs to sign in again on the device that made this
request.
*/
FIRAuthErrorCodeUserTokenExpired = 17021,
/*
Indicates an invalid API key was supplied in the request.
*/
FIRAuthErrorCodeInvalidAPIKey = 17023,
/*
Indicates that an attempt was made to reauthenticate with a user which is not the current
user.
*/
FIRAuthErrorCodeUserMismatch = 17024,
/*
Indicates an attempt to link with a credential that has already been linked with a
different Firebase account
*/
FIRAuthErrorCodeCredentialAlreadyInUse = 17025,
/*
Indicates an attempt to set a password that is considered too weak.
*/
FIRAuthErrorCodeWeakPassword = 17026,
/*
Indicates the App is not authorized to use Firebase Authentication with the
provided API Key.
*/
FIRAuthErrorCodeAppNotAuthorized = 17028,
/*
Indicates the OOB code is expired.
*/
FIRAuthErrorCodeExpiredActionCode = 17029,
/*
Indicates the OOB code is invalid.
*/
FIRAuthErrorCodeInvalidActionCode = 17030,
/*
Indicates that there are invalid parameters in the payload during a "send password reset
* email" attempt.
*/
FIRAuthErrorCodeInvalidMessagePayload = 17031,
/*
Indicates that the sender email is invalid during a "send password reset email" attempt.
*/
FIRAuthErrorCodeInvalidSender = 17032,
/*
Indicates that the recipient email is invalid.
*/
FIRAuthErrorCodeInvalidRecipientEmail = 17033,
/*
Indicates an error occurred while attempting to access the keychain.
*/
FIRAuthErrorCodeKeychainError = 17995,
/*
Indicates an internal error occurred.
*/
FIRAuthErrorCodeInternalError = 17999,
Localize Firebase error messages in PT-BR
https://gist.github.com/Albejr/a38cdeac247ef177986c99629680afb4
catchError(err => {
const errorCode = err.code;
let errorMessage = this.VerifyErroCode(errorCode);
if (errorMessage == null) {
errorMessage = err.message;
}
console.log(errorMessage);
})
VerifyErroCode(errorCode: string): string {
// fonte: https://firebase.google.com/docs/reference/js/firebase.auth.Auth
// fonte: https://firebase.google.com/docs/auth/admin/errors?hl=pt-br
switch (errorCode) {
case 'auth/app-deleted':
return 'O banco de dados não foi localizado.';
case 'auth/expired-action-code':
return 'O código da ação o ou link expirou.';
case 'auth/invalid-action-code':
return 'O código da ação é inválido. Isso pode acontecer se o código estiver malformado ou já tiver sido usado.';
case 'auth/user-disabled':
return 'O usuário correspondente à credencial fornecida foi desativado.';
case 'auth/user-not-found':
return 'O usuário não correponde à nenhuma credencial.';
case 'auth/weak-password':
return 'A senha é muito fraca.';
case 'auth/email-already-in-use':
return 'Já existi uma conta com o endereço de email fornecido.';
case 'auth/invalid-email':
return 'O endereço de e-mail não é válido.';
case 'auth/operation-not-allowed':
return 'O tipo de conta correspondente à esta credencial, ainda não encontra-se ativada.';
case 'auth/account-exists-with-different-credential':
return 'E-mail já associado a outra conta.';
case 'auth/auth-domain-config-required':
return 'A configuração para autenticação não foi fornecida.';
case 'auth/credential-already-in-use':
return 'Já existe uma conta para esta credencial.';
case 'auth/operation-not-supported-in-this-environment':
return 'Esta operação não é suportada no ambiente que está sendo executada. Verifique se deve ser http ou https.';
case 'auth/timeout':
return 'Excedido o tempo de resposta. O domínio pode não estar autorizado para realizar operações.';
case 'auth/missing-android-pkg-name':
return 'Deve ser fornecido um nome de pacote para instalação do aplicativo Android.';
case 'auth/missing-continue-uri':
return 'A próxima URL deve ser fornecida na solicitação.';
case 'auth/missing-ios-bundle-id':
return 'Deve ser fornecido um nome de pacote para instalação do aplicativo iOS.';
case 'auth/invalid-continue-uri':
return 'A próxima URL fornecida na solicitação é inválida.';
case 'auth/unauthorized-continue-uri':
return 'O domínio da próxima URL não está na lista de autorizações.';
case 'auth/invalid-dynamic-link-domain':
return 'O domínio de link dinâmico fornecido, não está autorizado ou configurado no projeto atual.';
case 'auth/argument-error':
return 'Verifique a configuração de link para o aplicativo.';
case 'auth/invalid-persistence-type':
return 'O tipo especificado para a persistência dos dados é inválido.';
case 'auth/unsupported-persistence-type':
return 'O ambiente atual não suportar o tipo especificado para persistência dos dados.';
case 'auth/invalid-credential':
return 'A credencial expirou ou está mal formada.';
case 'auth/wrong-password':
return 'Senha incorreta.';
case 'auth/invalid-verification-code':
return 'O código de verificação da credencial não é válido.';
case 'auth/invalid-verification-id':
return 'O ID de verificação da credencial não é válido.';
case 'auth/custom-token-mismatch':
return 'O token está diferente do padrão solicitado.';
case 'auth/invalid-custom-token':
return 'O token fornecido não é válido.';
case 'auth/captcha-check-failed':
return 'O token de resposta do reCAPTCHA não é válido, expirou ou o domínio não é permitido.';
case 'auth/invalid-phone-number':
return 'O número de telefone está em um formato inválido (padrão E.164).';
case 'auth/missing-phone-number':
return 'O número de telefone é requerido.';
case 'auth/quota-exceeded':
return 'A cota de SMS foi excedida.';
case 'auth/cancelled-popup-request':
return 'Somente uma solicitação de janela pop-up é permitida de uma só vez.';
case 'auth/popup-blocked':
return 'A janela pop-up foi bloqueado pelo navegador.';
case 'auth/popup-closed-by-user':
return 'A janela pop-up foi fechada pelo usuário sem concluir o login no provedor.';
case 'auth/unauthorized-domain':
return 'O domínio do aplicativo não está autorizado para realizar operações.';
case 'auth/invalid-user-token':
return 'O usuário atual não foi identificado.';
case 'auth/user-token-expired':
return 'O token do usuário atual expirou.';
case 'auth/null-user':
return 'O usuário atual é nulo.';
case 'auth/app-not-authorized':
return 'Aplicação não autorizada para autenticar com a chave informada.';
case 'auth/invalid-api-key':
return 'A chave da API fornecida é inválida.';
case 'auth/network-request-failed':
return 'Falha de conexão com a rede.';
case 'auth/requires-recent-login':
return 'O último horário de acesso do usuário não atende ao limite de segurança.';
case 'auth/too-many-requests':
return 'As solicitações foram bloqueadas devido a atividades incomuns. Tente novamente depois que algum tempo.';
case 'auth/web-storage-unsupported':
return 'O navegador não suporta armazenamento ou se o usuário desativou este recurso.';
case 'auth/invalid-claims':
return 'Os atributos de cadastro personalizado são inválidos.';
case 'auth/claims-too-large':
return 'O tamanho da requisição excede o tamanho máximo permitido de 1 Megabyte.';
case 'auth/id-token-expired':
return 'O token informado expirou.';
case 'auth/id-token-revoked':
return 'O token informado perdeu a validade.';
case 'auth/invalid-argument':
return 'Um argumento inválido foi fornecido a um método.';
case 'auth/invalid-creation-time':
return 'O horário da criação precisa ser uma data UTC válida.';
case 'auth/invalid-disabled-field':
return 'A propriedade para usuário desabilitado é inválida.';
case 'auth/invalid-display-name':
return 'O nome do usuário é inválido.';
case 'auth/invalid-email-verified':
return 'O e-mail é inválido.';
case 'auth/invalid-hash-algorithm':
return 'O algoritmo de HASH não é uma criptografia compatível.';
case 'auth/invalid-hash-block-size':
return 'O tamanho do bloco de HASH não é válido.';
case 'auth/invalid-hash-derived-key-length':
return 'O tamanho da chave derivada do HASH não é válido.';
case 'auth/invalid-hash-key':
return 'A chave de HASH precisa ter um buffer de byte válido.';
case 'auth/invalid-hash-memory-cost':
return 'O custo da memória HASH não é válido.';
case 'auth/invalid-hash-parallelization':
return 'O carregamento em paralelo do HASH não é válido.';
case 'auth/invalid-hash-rounds':
return 'O arredondamento de HASH não é válido.';
case 'auth/invalid-hash-salt-separator':
return 'O campo do separador de SALT do algoritmo de geração de HASH precisa ser um buffer de byte válido.';
case 'auth/invalid-id-token':
return 'O código do token informado não é válido.';
case 'auth/invalid-last-sign-in-time':
return 'O último horário de login precisa ser uma data UTC válida.';
case 'auth/invalid-page-token':
return 'A próxima URL fornecida na solicitação é inválida.';
case 'auth/invalid-password':
return 'A senha é inválida, precisa ter pelo menos 6 caracteres.';
case 'auth/invalid-password-hash':
return 'O HASH da senha não é válida.';
case 'auth/invalid-password-salt':
return 'O SALT da senha não é válido.';
case 'auth/invalid-photo-url':
return 'A URL da foto de usuário é inválido.';
case 'auth/invalid-provider-id':
return 'O identificador de provedor não é compatível.';
case 'auth/invalid-session-cookie-duration':
return 'A duração do COOKIE da sessão precisa ser um número válido em milissegundos, entre 5 minutos e 2 semanas.';
case 'auth/invalid-uid':
return 'O identificador fornecido deve ter no máximo 128 caracteres.';
case 'auth/invalid-user-import':
return 'O registro do usuário a ser importado não é válido.';
case 'auth/invalid-provider-data':
return 'O provedor de dados não é válido.';
case 'auth/maximum-user-count-exceeded':
return 'O número máximo permitido de usuários a serem importados foi excedido.';
case 'auth/missing-hash-algorithm':
return 'É necessário fornecer o algoritmo de geração de HASH e seus parâmetros para importar usuários.';
case 'auth/missing-uid':
return 'Um identificador é necessário para a operação atual.';
case 'auth/reserved-claims':
return 'Uma ou mais propriedades personalizadas fornecidas usaram palavras reservadas.';
case 'auth/session-cookie-revoked':
return 'O COOKIE da sessão perdeu a validade.';
case 'auth/uid-alread-exists':
return 'O indentificador fornecido já está em uso.';
case 'auth/email-already-exists':
return 'O e-mail fornecido já está em uso.';
case 'auth/phone-number-already-exists':
return 'O telefone fornecido já está em uso.';
case 'auth/project-not-found':
return 'Nenhum projeto foi encontrado.';
case 'auth/insufficient-permission':
return 'A credencial utilizada não tem permissão para acessar o recurso solicitado.';
case 'auth/internal-error':
return 'O servidor de autenticação encontrou um erro inesperado ao tentar processar a solicitação.';
default:
return null;
}
}
IOS Auth errors are:
Name: Hash; RawValue(code):
- AccountExistsWithDifferentCredential: 10; 17012
- InvalidEmail: 6; 17008
- NetworkError: 15; 17020
- UserDisabled: 3; 17005
- UserMismatch: 18; 17024
- UserNotFound: 9; 17011
- WeakPassword: 20; 17026
- InternalError: 23; 17999
- InvalidAPIKey: 17; 17023
- KeychainError: 22; 17995
- WrongPassword: 7; 17009
- NoSuchProvider: 13; 17016
- TooManyRequests: 8; 17010
- AppNotAuthorized: 21; 17028
- InvalidUserToken: 14; 17017
- UserTokenExpired: 16; 17021
- EmailAlreadyInUse: 5; 17007
- InvalidCredential: 2; 17004
- InvalidCustomToken: 0; 17000
- CustomTokenMismatch: 1; 17002
- OperationNotAllowed: 4; 17006
- RequiresRecentLogin: 11; 17014
- ProviderAlreadyLinked: 12; 17015
- CredentialAlreadyInUse: 19; 17025
Here's the full list of error codes from the Firebase website:
https://www.firebase.com/docs/web/guide/user-auth.html#section-full-error

wrong float calculation with spriteKit, always getting same result

I'm doing a method which creates you a custom sprite with a platform image and many invisible boxes to do the physic body . In this method I make three principal objects: the sprite image (platform), two "walls" with physics bodies (one at the top left and one at the top right of the sprite) and the ground which are boxes that goes along the ground between the walls.
I want to focus the single line of code which is making troubles.
As you can see in the image, I'm getting a result of 0.600000024 allways, whatever the value of "totalCajas" is. In this case the variable "totalCajas" is equal to 10 and the minaPek.size.width value is always 300 in this case so normally
(minaPek.size.width/500 == 0.6) - (10/100 == 0.1) should be equal to 0.5
So I don't understand why I'm getting this error. Any help would be apreciated!!
Let me explain you two simple things about the method, the param pos (position) are degrees and it's exactly like the x position of the sprite.
The param distMoon is the y position. It's actually the radius.
Size obviously is the size of the sprite. Thank you very much in advance for learnCocos2D cause he is always faster.
-(void)plataformaCustom:(CGFloat)pos Altura:(CGFloat)distMoon size:(CGSize)Size
{
XYZCajas *minaPek = [[XYZCajas alloc]crearMinaMed];
[minaPek setSize:Size];
[minaPek setDistanciaLuna:distMoon];
[self.world addChild:minaPek];
NSArray *temp = [NSArray arrayWithObjects:minaPek, nil];
[objetosMovimiento addObjectsFromArray:temp];
[superCaja setObjectsMovimiento:objetosMovimiento];
//A CONTINUACION creo un int con el numero total de cajas. Me servirá para posteriormente posicionarlas en los extremos/saber cuantos grados tienen
int totalCajas = minaPek.size.width / 20;
//A CONTINUACION Creo un bool que me hará saber cuando tengo colocada la pared izquierda
bool paredIzquierda = NO;
bool paredDerecha = NO;
for (totalCajas; totalCajas >=0; totalCajas--)
{
//APUNTE Cada 100 de ancho de la mina = 0.2 grados de distancia de la pared
// la distancia entre caja y caja es de 0.1
//A CONTINUACION
//coloco la pared izquierda.
if (paredIzquierda == NO)
{
XYZCajas *paredIzq =[[XYZCajas alloc]crearParedSinImagen];
[paredIzq setGrados:-1*(minaPek.size.width/500)];
[paredIzq setDistanciaLuna:distMoon+5];
[paredIzq setName:#"paredIzqPrueba"];
[self.world addChild:paredIzq];
NSArray *temp2 = [NSArray arrayWithObjects:paredIzq, nil];
[objetosCajas addObjectsFromArray:temp2];
[superCaja setObjects:objetosCajas];
paredIzquierda = YES;
totalCajas --;
}
//A CONTINUACION
//coloco la pared derecha
if (paredDerecha == NO)
{
XYZCajas *paredDer =[[XYZCajas alloc]crearParedSinImagen];
[paredDer setGrados:minaPek.size.width/500];
[paredDer setDistanciaLuna:distMoon+5];
[self.world addChild:paredDer];
NSArray *temp2 = [NSArray arrayWithObjects:paredDer, nil];
[objetosCajas addObjectsFromArray:temp2];
[superCaja setObjects:objetosCajas];
paredDerecha = YES;
totalCajas --;
}
//A CONTINUACION
//creamos cajas
XYZCajas *caja22 =[[XYZCajas alloc]crearCajaSinImagen];
float gradosCaja = ((minaPek.size.width/500) - (totalCajas/100));
[caja22 setGrados:gradosCaja];
[caja22 setDistanciaLuna:distMoon+20];
[self.world addChild:caja22];
NSArray *temp2 = [NSArray arrayWithObjects:caja22, nil];
[objetosCajas addObjectsFromArray:temp2];
[superCaja setObjects:objetosCajas];
}

Plone/Dexterity schema.Choice not allowing Spanish characters

In Plone 4.1.2 I created a myContentType with Dexterity. It has 3 zope.schema.Choice fields. Two of them take their values from a hardcoded vocabulary and the other one from a dynamic vocabulary. In both cases, if I choose a value that has Spanish accents, when I save the add form the selection is gone and doesn't show up in the view form (without showing any error message). But if I choose a non accented value everything works fine.
Any advise on how to solve this problem?
(David; I hope this is what you asked me for)
# -*- coding: utf-8 -*-
from five import grok
from zope import schema
from plone.directives import form, dexterity
from zope.component import getMultiAdapter
from plone.namedfile.interfaces import IImageScaleTraversable
from plone.namedfile.field import NamedBlobFile, NamedBlobImage
from plone.formwidget.contenttree import ObjPathSourceBinder
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from zope.schema.interfaces import IVocabularyFactory
from z3c.formwidget.query.interfaces import IQuerySource
from zope.component import queryUtility
from plone.formwidget.masterselect import (
_,
MasterSelectField,
MasterSelectBoolField,
)
from plone.app.textfield.interfaces import ITransformer
from plone.indexer import indexer
from oaxaca.newcontent import ContentMessageFactory as _
from oaxaca.newcontent.config import OAXACA
from types import UnicodeType
_default_encoding = 'utf-8'
def _encode(s, encoding=_default_encoding):
try:
return s.encode(encoding)
except (TypeError, UnicodeDecodeError, ValueError):
return s
def _decode(s, encoding=_default_encoding):
try:
return unicode(s, encoding)
except (TypeError, UnicodeDecodeError, ValueError):
return s
view = view.encode('utf-8')
def getSlaveVocab(master):
results = []
if master in OAXACA:
results = sorted(OAXACA[master])
return SimpleVocabulary.fromValues(results)
class IFicha(form.Schema, IImageScaleTraversable):
"""Describes a ficha
"""
tipoMenu = schema.Choice(
title=_(u"Tipo de evento"),
description=_(u"Marque la opción que aplique o "
"seleccione otro si ninguna aplica"),
values=(
u'Manifestación en lugar público',
u'Toma de instalaciones municipales',
u'Toma de instalaciones estatales',
u'Toma de instalaciones federales',
u'Bloqueo de carretera municipal',
u'Bloqueo de carretera estatal',
u'Bloqueo de carretera federal',
u'Secuestro de funcionario',
u'Otro',),
required=False,
)
tipoAdicional = schema.TextLine(
title=_(u"Registre un nuevo tipo de evento"),
description=_(u"Use este campo solo si marcó otro en el menú de arriba"),
required=False
)
fecha = schema.Date(
title=_(u"Fecha"),
description=_(u"Seleccione el día en que ocurrió el evento"),
required=False
)
municipio = MasterSelectField(
title=_(u"Municipio"),
description=_(u"Seleccione el municipio donde ocurrió el evento"),
required=False,
vocabulary="oaxaca.newcontent.municipios",
slave_fields=(
{'name': 'localidad',
'action': 'vocabulary',
'vocab_method': getSlaveVocab,
'control_param': 'master',
},
)
)
localidad = schema.Choice(
title=_(u"Localidad"),
description=_(u"Seleccione la localidad donde ocurrió el evento."),
values=[u'',],
required=False,
)
actores = schema.Text(
title=_(u"Actores"),
description=_(u"Liste las agrupaciones y los individuos que participaron en el evento"),
required=False,
)
demandas = schema.Text(
title=_(u"Demandas"),
description=_(u"Liste las demandas o exigencias de los participantes"),
required=False
)
depResponsable = schema.Text(
title=_(u"Dependencias"),
description=_(u"Liste las dependencias gubernamentales responsables de atender las demandas"),
required=False
)
seguimiento = schema.Text(
title=_(u"Acciones de seguimiento"),
description=_(u"Anote cualquier accion de seguimiento que se haya realizado"),
required=False
)
modulo = schema.Choice(
title=_(u"Informa"),
description=_(u"Seleccione el módulo que llena esta ficha"),
values=(
u'M1',
u'M2',
u'M3',
u'M4',
u'M5',
u'M6',
u'M7',
u'M8',
u'M9',
u'M10',
u'M11',
u'M12',
u'M13',
u'M14',
u'M15',
u'M16',
u'M17',
u'M18',
u'M19',
u'M20',
u'M21',
u'M22',
u'M23',
u'M24',
u'M25',
u'M26',
u'M27',
u'M28',
u'M29',
u'M30',),
required=False
)
imagen1 = NamedBlobImage(
title=_(u"Imagen 1"),
description=_(u"Subir imagen 1"),
required=False
)
imagen2 = NamedBlobImage(
title=_(u"Imagen 2"),
description=_(u"Subir imagen 2"),
required=False
)
anexo1 = NamedBlobFile(
title=_(u"Anexo 1"),
description=_(u"Subir archivo 1"),
required=False
)
anexo2 = NamedBlobFile(
title=_(u"Anexo 2"),
description=_(u"Subir archivo 2"),
required=False
)
#indexer(IFicha)
def textIndexer(obj):
"""SearchableText contains fechaFicha, actores, demandas, municipio and localidad as plain text.
"""
transformer = ITransformer(obj)
text = transformer(obj.text, 'text/plain')
return '%s %s %s %s %s' % (obj.fecha,
obj.actores,
obj.demandas,
obj.municipio,
obj.localidad)
grok.global_adapter(textIndexer, name='SearchableText')
class View(grok.View):
"""Default view (called "##view"") for a ficha.
The associated template is found in ficha_templates/view.pt.
"""
grok.context(IFicha)
grok.require('zope2.View')
grok.name('view')
I found the same problem some months ago on early development of collective.nitf.
The tokens on a vocabulary must be normalized; this is how I solved it:
# -*- coding: utf-8 -*-
import unicodedata
…
class SectionsVocabulary(object):
"""Creates a vocabulary with the sections stored in the registry; the
vocabulary is normalized to allow the use of non-ascii characters.
"""
grok.implements(IVocabularyFactory)
def __call__(self, context):
registry = getUtility(IRegistry)
settings = registry.forInterface(INITFSettings)
items = []
for section in settings.sections:
token = unicodedata.normalize('NFKD', section).encode('ascii', 'ignore').lower()
items.append(SimpleVocabulary.createTerm(section, token, section))
return SimpleVocabulary(items)
grok.global_utility(SectionsVocabulary, name=u'collective.nitf.Sections')
Plone uses gettext for internationalization. The bulletproof approach would be to implement your custom functionality in English and use locales for your specific language. Look at the relevant parts of the community manual on how this is done. Since you already setup a MessageFactory you could even use a tool like e.g. zettwerk.i18nduder for quick extraction of message strings.
I found a partial explanation/solution here. I can get the Spanish characters in the view form if i do:
-- coding: utf-8 --
from plone.directives import form
from five import grok
from zope import schema
from plone.directives import form, dexterity
from zope.schema.vocabulary import SimpleVocabulary
myVocabulary = SimpleVocabulary.fromItems((
(u"Foo", "id_foó"),
(u"Baroo", "id_baroó")))
class IPrueba(form.Schema):
tipoMenu = schema.Choice(
title=_(u"Tipo de evento"),
description=_(u"Marque la opción que aplique o "
"seleccione otro si ninguna aplica"),
vocabulary=myVocabulary,
required=False,
)

Resources