How to use FTS in SQLite with Monotouch for iOS

前端 未结 2 662
北海茫月
北海茫月 2020-12-18 16:06

I\'m looking to build an iOS app using Monotouch that has a rather large sqlite db full of text. I need to provide fast searching over this text.

My best solution ri

相关标签:
2条回答
  • 2020-12-18 16:27

    As I mentioned in my comment above I got this working and since Stack Overflow has really helped me out I wanted to contribute a little to give back to the community.
    Disclaimer
    This is coming from a .NET developer who is a N00B when it comes to iOS/MacOS/XCode/Monotouch.
    Although I tested this out on the iPad simulator I have yet to test it out on an actual device.
    End disclaimer

    This is a quick how-to compile your own version of SQLite and include it in your Monotouch project with the goal of supporting Full text search.

    Step 1: Download the SQLite amalgamation file.

    This includes all of SQLite in one file.
    http://www.sqlite.org/download.html

    Step 2: Compile the SQLite source in Xcode for iOS.

    There is a good walkthrough on how to do this here:
    http://pp.hillrippers.ch/blog/2009/08/08/Static+SQLite+Library+with+Unicode+Support+for+the+iPhone/

    I followed steps 1-5, skipped #6 since we're not adding additional headers.

    Instead of using the compile flags used in the walk through I used:
    SQLITE_ENABLE_COLUMN_METADATA
    SQLITE_ENABLE_FTS4

    There may be others you want to add as well.
    These compile flags are added in XCode, to the "Build" tab of the project under "Preprocessor Macros".

    Once you've compiled this you should have "mylibrary.a".

    Step 3: Include this file in your MonoDevelop project
    Add mylibrary.a into MonoDevelop as any other file, right click it and make sure the build action is 'Nothing'.

    In your project options select "iPhone Build". You need to add additional mtouch arguments. Add the following

    -gcc_flags "-L${ProjectDir} -lmylibrary -force_load ${ProjectDir}/mylibrary.a"
    

    Step 4: Build a c# wrapper
    You could probably find a good wrapper to include at this point but I just quickly rolled my own.

    For a good tutorial on writing an SQLite wrapper in C# check this page out:
    http://www.switchonthecode.com/tutorials/csharp-tutorial-writing-a-dotnet-wrapper-for-sqlite

    Because your library is a part of the project you don't need to reference the library by name but instead use the "__Internal" keyword. *NOTE THERE ARE TWO UNDERSCORES IN "__INTERNAL" * (Don't ask me how much time I wasted before I realized that)

    Here's a sample of one of mine

    [DllImport ("__Internal", EntryPoint="sqlite3_open")]  
    static extern int sqlite3_open_v2(string filename, out IntPtr db);
    

    There's obviously a lot more to putting together a wrapper, but there's lots of info out there on how to do that. One gotcha is to properly marshal the strings you get returned from SQLite. (see http://blog.gebhardtcomputing.com/2007/11/marshal-utf8-strings-in-net.html for more info on Marshaling)

    This was intended to be a quick walkthrough on getting a native library compiled in into MonoDevelop/monotouch, and I hope it helps someone.

    0 讨论(0)
  • 2020-12-18 16:34

    You would have to do the same thing, build your own libsqlite3.a, and mangle all the public exports so it doesn't conflict with the libsqlite loaded by the system, and then you would need to modify whatever library you want to bind to sqlite to [DllImport ("__Internal")] instead of libsqlite.

    0 讨论(0)
提交回复
热议问题