Zip/Rar files with SWIFT - objective-c

I am new to SWIFT and I just started implementing my first application for OS X. I created a simple project and decided Ill look into different frameworks for using zip/rar files. I started with ZipArchive as recommended but couldn't make it work in my project - didn't even compile (probably something wrong with my setup), I had similar experience with Objective-Zip and SSZipArchive. Finally I stumbled on the framework zip zap which attached to my project perfectly.
I looked into the examples:
ZZArchive* oldArchive = [ZZArchive archiveWithURL:[NSURL fileURLWithPath:#"/tmp/old.zip"] error:nil];
ZZArchiveEntry* firstArchiveEntry = oldArchive.entries[0];
NSLog(#"The first entry's uncompressed size is %lu bytes.", (unsigned long)firstArchiveEntry.uncompressedSize);
NSLog(#"The first entry's data is: %#.", [firstArchiveEntry newDataWithError:nil]);
but I couldn't make it work with SWIFT. The problem I faced is that I couldn't create a NSURL that worked with the ZZArchive.
let zip:ZZArchive = ZZArchive(NSURL(fileURLWithPath:"/Users/../tesData/test.zip"))
led to
fatal error: unexpectedly found nil while unwrapping an Optional value
and everything else I tried either didn't compile with a unwrapping error or compiled but on execution led to this error.
Can someone please either help me solve my unzipping problem, or lead me to a solution of how to zip/unzip/read zip/rar/cbr files with swift.

This should fix it
var path = NSURL.fileURLWithPath("/Users/../tesData/test.zip")
var archive: ZZArchive = ZZArchive(URL:(fileURLWithPath:path!), error: &err)
Here is an implementation of zzzip in swift
//Declare
var err: NSError? = NSError()
var path = NSURL.fileURLWithPath("/PathToZipFile/file.zip")
var URL3 = NSURL.fileURLWithPath("/pathanywhereinsystemtosaveunzipedfolder/")
var URL2 = NSURL.fileURLWithPath("/PathToUnzippedFile/file.xxx")
var fileManager = NSFileManager.defaultManager() //1
let archive: ZZArchive = ZZArchive(URL:(fileURLWithPath:path!), error: &err)//2-3
//Create Folder
fileManager.createDirectoryAtURL(URL3!, withIntermediateDirectories: true, attributes: nil, error: &err)
//Write First entry of archive to file
var k = archive.entries[0].newDataWithError(nil)
k.writeToURL(URL2!, atomically: false)
This works for small text files and images. it does have its limitations due to no errorchecking and only writing the first archive entery to a file. If any paths are wrong you will end with errors as soon as you try and compile.

Related

With Kotlin write to SD-card on Android

I have read a lot of questions and answers, but are not really satisfied and successful
My Problem: write with Kotlin to a sdcard to a specific directory
Working is
var filenamex = "export.csv"
var patt = getExternalFilesDirs(null)
var path = patt[1]
//create fileOut object
var fileOut = File(path, filenamex)
//create a new file
fileOut.createNewFile()
with getExternalFIlesDirs() I get the external storage and the sdcard. With path = patt[1] i get the adress of my sd-card.
this is
"/storage/105E-XXXX/Android/data/com.example.myApp/files"
This works to write data in this directory.
But I would like to write into an other directory, for example
"/sdcard/myApp"
A lot of examples say, this should work, bit it does not.
So I tried to take
"/storage/105E-XXXX/myApp"
Why doesn't it work? Ist the same beginning of storage /storage/105E-XXXX/, so it is MY sd-card.?
As I mentioned, it works on the sd-card, so it is not a problem of write-permission to the sdcard?
Any idea?
(I also failed with FileOutputStream and other things)
Try Out this..
var filenamex = "export.csv"
var path = getExternalStorageDirectory() + "//your desired folder"
var fileOut = File(path, filenamex)
fileOut.createNewFile()

Kotlin - get Firebase Image DownloadUrl returns "com.google.android.gms.tasks.zzu"

I am trying to upload images to Real time Firebase Database by creating two folders using Compressor library and need to display image like messenger with username but i am unable to display image due to url issue
var filePath = mStorageRef!!.child("chat_profile_images")
.child(userId + ".jpg")
//Create another directory for thumbimages ( smaller, compressed images)
var thumbFilePath = mStorageRef!!.child("chat_profile_images")
.child("thumbs")
.child(userId + ".jpg")
filePath.putFile(resultUri)
.addOnCompleteListener{
task: Task<UploadTask.TaskSnapshot> ->
if (task.isSuccessful) {
//Let's get the pic url
var donwloadUrl = task.result?.storage?.downloadUrl.toString()
Log.d(TAG, "Profilepic link: $donwloadUrl")
//Upload Task
var uploadTask: UploadTask = thumbFilePath
.putBytes(thumbByteArray)
uploadTask.addOnCompleteListener{
task: Task<UploadTask.TaskSnapshot> ->
var thumbUrl = task.getResult()?.storage?.downloadUrl.toString()
Log.d(TAG, "Profilepic link: $thumbUrl")
i tried to change downloadUrl
filepath.downloadUrl.toString
thumbFilePath.downloadUrl.toString
but both these values getting "com.google.android.gms.tasks.zzu"
i also tried to change
task.result.sessionurl.downloadUrl.toString
for this one i am getting downloadUrl but not a complete solution for my problem as still i cannot display image i need to get thumbUrl downloadUrl
You have the exact same and very common misunderstanding as in this question, except it's in java. You should follow the documentation here to understand get getDownloadUrl works. As you can see from the linked API documentation, it's not a property getter, it's actually a method that returns a Task<Uri> that tracks the asynchronous fetch of the URL you want, just like the upload task:
filePath.downloadUrl
.addOnSuccessListener { urlTask ->
// download URL is available here
val url = urlTask.result.toString()
}.addOnFailureListener { e ->
// Handle any errors
}
This will only work after the upload is fully complete.
Correct way of getting download link after uploading
here
Just putting out there, I also encounter the same problem,
but both these values getting "com.google.android.gms.tasks.zzu"
but it wasn't the same mistake from the OP
used addOnCompleteListener instead of addOnSuccesslistener
My Error code:
imageRef.downloadUrl.addOnCompleteListener { url ->
val imageURL = url.toString()
println("imageURL: $imageURL , url: $url")
addUserToDatabase(imageURL)
}

CFURLCopyResourcePropertyForKey failed because passed URL no scheme

I have a program that saves a file to the iCloud and this has worked great for iOS7, but now I get this error with iOS8 and cannot seem to find the answer on how to fix it. Anyone else had this problem? Any ideas would be greatly appreciated.
The Error:
CFURLCopyResourcePropertyForKey failed because it was passed this URL which has no scheme: /var/mobile/Containers/Data/Application/ASFHDDE3-B1BB-41D7-A47C-DCC328362W21/Documents/mypictostore.png
The Line of Code Throws Error:
[fileManager setUbiquitous:YES itemAtURL:backupUrl destinationURL:[[ubiq URLByAppendingPathComponent:#"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError];
URLS:
destinationURL: file:///private/var/mobile/Library/Mobile%20Documents/ABC23455~MY-Program/
backupUrl: /var/mobile/Containers/Data/Application/ASDFGEEW-B1BB—6FR6-A47C-DCCF21876D36/Documents/mypic.png
Thank you,
Jon
For me this problem was fixed by adding
file://
right before the file path address like this:
var filePath = "file://\(fileURLpath)"
Or maybe you can use NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mypictostore", ofType: "png")!) instead of using NSURL(string: NSBundle.mainBundle().pathForResource("mypictostore", ofType: "png")!)
Look this link for Objective-c answer: CFURLSetResourcePropertyForKey failed when disable data backup on NSDocumentDirectory
Older Swift version answer:
var str:String = "/var/mobile/Containers/Data/Application/3039975A-5E05-4A4C-8000-55C681A7C35F/Documents/index.html"
var url:URL = URL.init(fileURLWithPath: str)
Swift 4 Answer:
var str:String = "/var/mobile/Containers/Data/Application/3039975A-5E05-4A4C-8000-55C681A7C35F/Documents/index.html"
var url:URL = URL(string: str)!
Depending on what you need to do with the path, you may need to prepend the scheme file://. See more at documentation/foundation/url
If you need the file path, use fileURLWithPath:
let imageURL = URL(fileURLWithPath: imagePath)
it will give you the path as
file:///var/mobile/Containers/Data/Application/7C1D854B-8A2E-4FF0-BD30-0652AEE10B6F/Documents/image_8ZMAM.jpg
If you need the path without the scheme, use string:
let imageURL = URL(string: imagePath)
it will give you the path as
/var/mobile/Containers/Data/Application/7C1D854B-8A2E-4FF0-BD30-0652AEE10B6F/Documents/image_8ZMAM.jpg
look, I find this,The url is The location to write the data into. we should tell the system a file path.
var filePath = "file://(fileURLpath)"
var url:URL = URL.init(fileURLWithPath: fileURLpath)
Data
You can also try this, I think the following code is great as if you are not sure any particular url is correct or not for the CFURLCopyResourcePropertyForKey
if testURL.isFileURL == false {
testURL = URL(fileURLWithPath: testURL.absoluteString)
}
var url = USL(fileUrlWithString: "/private/var/...")

Download font .ttf file from web and store on iPhone

Is it possible to download .ttf file from web and store it on iPhone. Then use that for for labels and all other stuff ? Because my client want to control fonts from database and don't want to just drop fonts to xcode project right away.
So in future if he wants to change font, he will add new font to database, app will recognize new font on web (thats already done with images, not a problem), download it and use as font.
Thanks.
Actually it is possible to dynamically add fonts to the iOS runtime like this:
NSData *fontData = /* your font-file data */;
CFErrorRef error;
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)inData);
CGFontRef font = CGFontCreateWithDataProvider(provider);
if (! CTFontManagerRegisterGraphicsFont(font, &error)) {
CFStringRef errorDescription = CFErrorCopyDescription(error)
NSLog(#"Failed to load font: %#", errorDescription);
CFRelease(errorDescription);
}
CFRelease(font);
CFRelease(provider);
Source: This Blog Article of Marco Arment.
It is possible. I created an example swift project in github. You have to just add the few line below.
var uiFont : UIFont?
let fontData = data
let dataProvider = CGDataProviderCreateWithCFData(fontData)
let cgFont = CGFontCreateWithDataProvider(dataProvider)
var error: Unmanaged<CFError>?
if !CTFontManagerRegisterGraphicsFont(cgFont, &error)
{
print("Error loading Font!")
} else {
let fontName = CGFontCopyPostScriptName(cgFont)
uiFont = UIFont(name: String(fontName) , size: 30)
}
Github project link
The fonts have to be set in the plist of your app, and that file cannot be changed during runtime, so you need to compile your project with the fonts already added to it.
You'll have to think in other way of implementing it.
You could use FontLabel (https://github.com/vtns/FontLabel) or smth. similar to load ttfs from the file system. I don't think that you can use downloaded fonts with a UILabel. Because you need the plist entries for each font.
Swift 4 solution by extension:
extension UIFont {
/**
A convenient function to create a custom font with downloaded data.
- Parameter data: The local data from the font file.
- Parameter size: Desired size of the custom font.
- Returns: A custom font from the data. `nil` if failure.
*/
class func font(withData data: Data, size: CGFloat) -> UIFont? {
// Convert Data to NSData for convenient conversion.
let nsData = NSData(data: data)
// Convert to CFData and prepare data provider.
guard let cfData = CFDataCreate(kCFAllocatorDefault, nsData.bytes.assumingMemoryBound(to: UInt8.self), nsData.length),
let dataProvider = CGDataProvider(data: cfData),
let cgFont = CGFont(dataProvider) else {
print("Failed to convert data to CGFont.")
return nil
}
// Register the font and create UIFont.
var error: Unmanaged<CFError>?
CTFontManagerRegisterGraphicsFont(cgFont, &error)
if let fontName = cgFont.postScriptName,
let customFont = UIFont(name: String(fontName), size: size) {
return customFont
} else {
print("Error loading Font with error: \(String(describing: error))")
return nil
}
}
}
Usage:
let customFont = UIFont.font(withData: data, size: 15.0)

How i retrieve data in iOS xCode SDK?

I am using Titanium. and I want to make Titanium Module (for iOS).
every thing is working fine. But, how i retrieve data in xCode whose i send through .js file.
in .js file
var data = "Mritunjay";
var oldData = "Singh";
var data = module_tset.findData({"newData":data,"oldData":oldData});
in xCode
-(id)findData:(NSMutableArray *)args
{
NSMutableArray *ary = [[NSMutableArray alloc]initWithArray:args];
// How i retrieve "newData" Value in xCode?
}
please help me..! thanks
First you should check the documentation for this.
Also, check the example moddevguide projects on GitHub, they have very simple and straightforward examples of how to do this.
In a nutshell heres the code to extract those arguments (assuming you setup this correctly).
-(id)findData:(id)args
{
ENSURE_SINGLE_ARG(args,NSDictionary); // Standard practice
NSString *newData_Pass = [TiUtils stringValue:[args objectForKey:#"newData"]];
// Now do something with newData!
}
Thats it!