How to integrate MuPDF 1.3 in iOS Project - ios

There is build-in PDF render engine for iOS, but it doesn't solve the "Transparency Flattening" issue. Hence I try to integrate MuPDF 1.3 into project.
I tried to use reference the MuPDF project, and it failed.
Then I build debug static libraries for each architecture, and use "Library Search Paths" and "Other Link Flags" to separate the linked library while building binary of different architecture, but XCode keeps showing "Undefined symbols for architecture armxxx".
Finally, I built the release version static library of MuPDF, which should compatible for all architecture, and XCode still keeps showing same thing as before.
Does there anyone integrate and compile MuPDF 1.3 successfully? Please give me some hint.
Thanks a lot.

Sorry for the late answer but it could help people a day or another.
As I had to integrate the MuPDF library into one of my (Swift) project, I generated
the static fat libraries and integrate them into Xcode.
Here you go with a step-by-step quick tutorial:
How to build the static fat library:
git clone --recursive git://git.ghostscript.com/mupdf.git
Go to mupdf/platform/ios
Open MuPDF.xcodeproj with Xcode.
Configure the scheme of the MuPDF target to Release.
Build and run the app on an iPhone simulator.
This will generate the library for platforms i386 and x86_64
Build and Run the app on a real iPhone device - use your own bundle id, certificate and provisioning profile.
This will generate the library for platforms armv7 and arm64
Go to mupdf/build/
You will find two folders that contains all built librairies: release-ios-i386-x86_64 and release-ios-armv7-arm64
Now you need to create fat libraries with all 4 architectures for the mupdf one and all its dependencies.
lipo -create ./*/libcurl.a -output 'libcurl.a' ; lipo -create ./*/libfreetype.a -output 'libfreetype.a' ; lipo -create ./*/libjbig2dec.a -output 'libjbig2dec.a' ; lipo -create ./*/libjpeg.a -output 'libjpeg.a' ; lipo -create ./*/libmujs.a -output 'libmujs.a' ; lipo -create ./*/libmupdf.a -output 'libmupdf.a' ; lipo -create ./*/libopenjpeg.a -output 'libopenjpeg.a' ; lipo -create ./*/libz.a -output 'libz.a'
How to integrate MuPDF into your project:
Add/import into your project:
All header files from mupdf/include/mupdf
All obj-c classes from mupdf/platform/ios/classes
The common.[h,m] files from mupdf/platform/ios
Add/import the previously generated fat libraries (8 files)
Configure the Library Search Path by adding the path to your library files.
For example $(inherited) $(PROJECT_DIR)/External/MuPDF/lib/
You should now be able to build and run your app with the library included.
Use the sample project to understand how the library works or any online tutorial.
Pro Tip:
The final fat libraries are pretty big all together (~ 46mb).
You could easily reduce the final size of your app by importing:
Under a release folder just the lib.a from mupdf/build/release-ios-armv7-arm64
Under a debug folder the big generated fat librairies from mupdf/build/
Set different Library Search Path for Debug and Release config.
Once done, you will be able to build and run on Debug on every simulator and devices. But only on devices for Release. Which in the end you need as your app, through, the AppStore
should only run on real devices. There is no need to include debug-simulator architecture static librairies.
Here is a screenshot of all imported files into my Xcode project:

The easiest way is probably to use the MuPDF CocoaPod, which I just created. There is an example application based on that pod.

Related

How to remove examples.o files from the framework in IOS?

I have use AFNetworking library using cocoapods. my project was running fine but when i drag third party framework in my existing project it give me error of duplication symbols in armv7.
I have listed out .o files in the framework using terminal
$ lipo frameworkName -info
$ lipo frameworkName -thin armv7 -output frameworkName.armv7
$ ar -t frameworkName.armv7
Its displaying some .o files which are also present in the AFnetworking library like AFURLSessionManager.o
When I try to remove those file using command
$ ar -d -sv frameworkName.armv7 AFURLSessionManager.o
its not removing those files.
For sake I have removed -ObjC flag from the Other Linker Flags but doing so my some other cocoapods libraries are not working.
Please assist me with the solution. Thanks in advance.
AFURLSessionManager.o appears when AFURLSessionManager.m is not added to target. Try to check Target Membership for AFURLSessionManager.m in File inspector. It should fix the issue.

Xcode 7 builds i386 instead of arm binary for Release-iphoneos

I moved from XCode 6 to XCode 7 and without any changes to the source, or project, or anything my Archive builds started to fail.
After research on the error that lipo produced:
lipo:.../Release-iphoneos/libSDWebImage.a and .../Release-iphonesimulator/libSDWebImage.a have the same architectures (i386) and can't be in the same fat output file
I found that the following:
In XCode 6 the lipo -info returns Architectures in the fat file: .../Release-iphoneos/libSDWebImage.a are: armv7 arm64 and Architectures in the fat file: .../Release-iphonesimulator/libSDWebImage.a are: i386 x86_64 which is correct. I have arm for iphone device and i386 for iphone simulator.
In XCode 7 these two files are the same, and have the i386 architecture! So framework scripts that uses lipo to join these two .a files into one fails.
Why XCode 7 suddenly stopped building my SDWebImage framework for arm? The project settings are unchanged, the library is the same, the scheme has Archive set to Release. Please help.
iMac:~ lukasz$ lipo -info /Users/lukasz/Library/Developer/Xcode/DerivedData/…-etcsjmgakpylpmgchumhnsqpyrev/Build/Intermediates/ArchiveIntermediates/adhoc-stage/BuildProductsPath/Release-iphoneos/libSDWebImage.a
input file /Users/lukasz/Library/Developer/Xcode/DerivedData/…-etcsjmgakpylpmgchumhnsqpyrev/Build/Intermediates/ArchiveIntermediates/adhoc-stage/BuildProductsPath/Release-iphoneos/libSDWebImage.a is not a fat file
Non-fat file: /Users/lukasz/Library/Developer/Xcode/DerivedData/…-etcsjmgakpylpmgchumhnsqpyrev/Build/Intermediates/ArchiveIntermediates/adhoc-stage/BuildProductsPath/Release-iphoneos/libSDWebImage.a is architecture: i386
iMac:~ lukasz$ lipo -info /Users/lukasz/Library/Developer/Xcode/DerivedData/…-etcsjmgakpylpmgchumhnsqpyrev/Build/Intermediates/ArchiveIntermediates/adhoc-stage/BuildProductsPath/Release-iphonesimulator/libSDWebImage.a
input file /Users/lukasz/Library/Developer/Xcode/DerivedData/…-etcsjmgakpylpmgchumhnsqpyrev/Build/Intermediates/ArchiveIntermediates/adhoc-stage/BuildProductsPath/Release-iphonesimulator/libSDWebImage.a is not a fat file
Non-fat file: /Users/lukasz/Library/Developer/Xcode/DerivedData/…-etcsjmgakpylpmgchumhnsqpyrev/Build/Intermediates/ArchiveIntermediates/adhoc-stage/BuildProductsPath/Release-iphonesimulator/libSDWebImage.a is architecture: i386
I ran into the same problem trying to build a multi-architecture framework on Xcode 7. It seems like you are building a static library, which is different, but could be related. I'm assuming you are using xcodebuild command (in an Aggregate target run script?) to build your library for different SDKs and then doing lipo at the end to join all of them.
The problem for me was that the framework/library being built is located in the build/UninstalledProducts folder, and what lives in the BUILD_DIR are symlinks to that. So most likely the libraries in your Release-iphoneos and Release-iphonesimulator are aliases to the same one, hence you see that they have the same architecture (i386 in your case).
To avoid this, navigate to the 'Build Settings' of your static library target in Xcode and ensure the following under 'Deployment':
Deployment Location is NO for release
Deployment Postprocessing is NO for release
You should see that the build no longer outputs UninstalledProducts folder and that all libraries/frameworks built in the BUILD_DIR are unique files, which should now have the correct architectures. You can then do whatever you like with them using lipo. You might have to delete your DerivedData before attempting the above.
For me, the fix was to set the 'Skip install' from Yes no No (which is the default). So insure that in addition to other two options mentioned by Andrew Wei. +1 for great analysis dude.

How to merge two .a files which is built for armv7 and i386?

I have 2 static library(.a) files. These 2 files are basically same library.
one is built for architecture armv7, another one is built for architecture i386.
Is it possible to merge these 2 libraries into 1 file?
Unfortunately, I don't have any source code to re-build them.
Thank you in advance :D
You need to get to know what can be done with the lipo and libtool command line tools, both of which come with Xcode.
Here's a tutorial that might get you started on the process.
The steps include something like:
lipo -info libFirst.a libSecond.a find out what architectures are in the .a files
lipo -extract armv7s libFirst.a -o libFirst_armv7s.a extract the architectures you want
libtool -static libFirst_armv7.a libSecond_armv7.a -o libCombined_armv7.a combine the architecture specific .a files into one
lipo -create libCombined_armv7.a libCombined_armv7s.a -o libCombined.a and this gives you the final .a library.
And here's some older documentation from Apple which describes how to use the tools to create combined static libraries.

Check supported architectures of framework in Objective-C

As requested by Apple in the next February (February 2014), every app submitted to AppStore needs to support Arm64 architecture. In my project, I used many static libraries (*.a) and I can check if these libs support arm64 arch. However, I don't know if some frameworks such as Facebook.framework supports this new arch. How can I check it?
Each framework is really just a directory - not even like a package directory, but a plain directory you can browse directly into with Finder. Go into the .framework folder, at the top level you'll find a file with the same name as the framework (for older frameworks that file may be located under a folder called Versions/A within the .framework folder).
That file is really a static library (.a) file, just without the extension. Check it as you would any static library (using file or lipo -info) and you'll see what binaries the file contains.
You'll also know through XCode though. If you switch your project to support arm64 and the libraries you are linking to do not have arm64 support, XCode will not finish linking when compiling for a device.
Check below command in Terminal
lipo -info yourlib.a
Output like :
Architectures in the fat file: yourlib.a are: i386 x86_64 armv7 arm64
In case Framework.framework
Go to inside framework like below
cd /Your_Path_/CocoaLumberjack.framework
then run command
lipo -info CocoaLumberjack

Develop an ebook reader on iPhone/iPad using MuPDF library

Can I develop an ebook reader on iphone/ipad using MuPDF library?
Do you have any good idea? Please help me with some good tutorials.
Sorry for the late answer but it could help people a day or another.
As I had to integrate the MuPDF library into one of my (Swift) project, I generated
the static fat libraries and integrate them into Xcode.
Here you go with a step-by-step quick tutorial:
How to build the static fat library:
git clone --recursive git://git.ghostscript.com/mupdf.git
Go to mupdf/platform/ios
Open MuPDF.xcodeproj with Xcode.
Configure the scheme of the MuPDF target to Release.
Build and run the app on an iPhone simulator.
This will generate the library for platforms i386 and x86_64
Build and Run the app on a real iPhone device - use your own bundle id, certificate and provisioning profile.
This will generate the library for platforms armv7 and arm64
Go to mupdf/build/
You will find two folders that contains all built librairies: release-ios-i386-x86_64 and release-ios-armv7-arm64
Now you need to create fat libraries with all 4 architectures for the mupdf one and all its dependencies.
lipo -create ./*/libcurl.a -output 'libcurl.a' ; lipo -create ./*/libfreetype.a -output 'libfreetype.a' ; lipo -create ./*/libjbig2dec.a -output 'libjbig2dec.a' ; lipo -create ./*/libjpeg.a -output 'libjpeg.a' ; lipo -create ./*/libmujs.a -output 'libmujs.a' ; lipo -create ./*/libmupdf.a -output 'libmupdf.a' ; lipo -create ./*/libopenjpeg.a -output 'libopenjpeg.a' ; lipo -create ./*/libz.a -output 'libz.a'
How to integrate MuPDF into your project:
Add/import into your project:
All header files from mupdf/include/mupdf
All obj-c classes from mupdf/platform/ios/classes
The common.[h,m] files from mupdf/platform/ios
Add/import the previously generated fat libraries (8 files)
Configure the Library Search Path by adding the path to your library files.
For example $(inherited) $(PROJECT_DIR)/External/MuPDF/lib/
You should now be able to build and run your app with the library included.
Use the sample project to understand how the library works or any online tutorial.
Pro Tip:
The final fat libraries are pretty big all together (~ 46mb).
You could easily reduce the final size of your app by importing:
Under a release folder just the lib.a from mupdf/build/release-ios-armv7-arm64
Under a debug folder the big generated fat librairies from mupdf/build/
Set different Library Search Path for Debug and Release config.
Once done, you will be able to build and run on Debug on every simulator and devices. But only on devices for Release. Which in the end you need as your app, through, the AppStore
should only run on real devices. There is no need to include debug-simulator architecture static librairies.
Here is a screenshot of all imported files into my Xcode project:
It is certainly possible to develop an ebook reader on iphone/ipad using MuPDF.
MuPDF is licensed both under the GNU GPL and under the Artifex commercial license. We have commercial licensees who do use MuPDF to implement ebook readers on ipad.
We also release a version of MuPDF for iOS via the iTunes app store (search for MuPDF) - so despite their sometimes unclear and arbitrary rules about what they will and won't allow, Apple clearly have no problem with "duplicating functionality" as a previous respondent suggested.
As to help with tutorials etc:
in the MuPDF source we have a doc directory that contains example source showing how to open/render/close a PDF file. We also have examples there that show how to work in multi-threaded worlds.
we have example android/iOS/windows/linux viewers in the source too.
we have simple command line tools (again with full source) that show how to render PDFs etc.
I would hope that this is enough to get a competent programmer moving.
While the GNU GPL version is released unsupported, we do offer support contracts to those who want them. Alternatively, pop along to the #ghostscript irc channel and we may be able to help with simple queries (though there is a limit to how much time we can invest in helping any single free user). Or, ask specific questions on here.

Resources