Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARC error with FMDB class after changes to building settings to compile SQLCipher

I followed the tutorial for compiling SQLCipher on iOS devices using a binary located here: http://sqlcipher.net/sqlcipher-binaries-ios-and-osx/

I've made several changes to build settings, adding header search path and C flags. Then after testing a compile of the sqlcipher, i didn't get any errors with the binary, but errors that did not exist before with FMDB started showing up like this:

FMDatabaseAdditions.m:137:19: Implicit declaration of function 'NSFileTypeForHFSTypeCode' is invalid in C99`

FMDatabaseAdditions.m:137:19: Implicit conversion of 'int' to 'NSString *' is disallowed with ARC`

FMDatabaseAdditions.m:137:15: Incompatible integer to pointer conversion initializing 'NSString *__strong' with an expression of type 'int'`

FMDatabaseAdditions.m:158:96: Values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead`

FMDatabaseAdditions.m:161:28: Implicit declaration of function 'NSHFSTypeCodeFromFileType' is invalid in C99`

like image 439
Liban Abdulle Avatar asked Jan 14 '14 10:01

Liban Abdulle


1 Answers

This error occurs when you play with targets in your project. The NSFileTypeForHFSTypeCode is only needed when you compile project against Mac OS target and should not be used if target is iPhone. Actually, on the new versions of XCode it seems the error occurs even if your project is targeted as iPhone . Old answer:

So we must rewrite applicationIDString implementation and put conditional flags:

    #if TARGET_OS_MAC && !TARGET_OS_IPHONE
    - (NSString*)applicationIDString {
       NSString *s = NSFileTypeForHFSTypeCode([self applicationID]);

       assert([s length] == 6);

       s = [s substringWithRange:NSMakeRange(1, 4)];


       return s;

    }
#endif

The condition if TARGET_OS_MAC will not replace the need of !TARGET_OS_IPHONE because TARGET_OS_IPHONE is actually a variant of TARGET_OS_MAC. So to avoid compile errors, add #if TARGET_OS_MAC && !TARGET_OS_IPHONE

Also below that part of code:

    - (void)setApplicationIDString:(NSString*)s {

       if ([s length] != 4) {
          NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]);
       }
        #if TARGET_OS_MAC && !TARGET_OS_IPHONE
       [self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])];
       #endif
   }

New answer:

I updated the code and rearranged methods to be more grouped on scope (conditions) in FMDatabaseAdditions.m :

        #if SQLITE_VERSION_NUMBER >= 3007017

        - (uint32_t)applicationID {

            uint32_t r = 0;

            FMResultSet *rs = [self executeQuery:@"pragma application_id"];

            if ([rs next]) {
                r = (uint32_t)[rs longLongIntForColumnIndex:0];
            }

            [rs close];

            return r;
        }

        - (void)setApplicationID:(uint32_t)appID {
            NSString *query = [NSString stringWithFormat:@"pragma application_id=%d", appID];
            FMResultSet *rs = [self executeQuery:query];
            [rs next];
            [rs close];
        }


        #if TARGET_OS_MAC && !TARGET_OS_IPHONE
        - (NSString*)applicationIDString {
            NSString *s = NSFileTypeForHFSTypeCode([self applicationID]);

            assert([s length] == 6);

            s = [s substringWithRange:NSMakeRange(1, 4)];


            return s;

        }

        - (void)setApplicationIDString:(NSString*)s {

            if ([s length] != 4) {
                NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]);
            }

            [self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])];
        }


        #endif

        #endif

Also to avoid other warnings I modified FMDatabaseAdditions.h

       #if SQLITE_VERSION_NUMBER >= 3007017

        ///-----------------------------------
        /// @name Application identifier tasks
        ///-----------------------------------

        /** Retrieve application ID

         @return The `uint32_t` numeric value of the application ID.

         @see setApplicationID:
         */

        - (uint32_t)applicationID;

        /** Set the application ID

         @param appID The `uint32_t` numeric value of the application ID.

         @see applicationID
         */

        - (void)setApplicationID:(uint32_t)appID;

        #if TARGET_OS_MAC && !TARGET_OS_IPHONE
        /** Retrieve application ID string

         @return The `NSString` value of the application ID.

         @see setApplicationIDString:
         */


        - (NSString*)applicationIDString;

        /** Set the application ID string

         @param string The `NSString` value of the application ID.

         @see applicationIDString
         */

        - (void)setApplicationIDString:(NSString*)string;
        #endif

        #endif
like image 134
ares777 Avatar answered Nov 14 '22 00:11

ares777