I get memory leak when I execute CTFontManagerRegisterGraphicsFont - ios

I am wondering why I am receiving memory leak in case when CTFontManagerRegisterGraphicsFont is called. Is it possible because it is debug build ? Or it is connected with wrong usage of the apple API?
public static func register(from url: URL) throws {
guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {
throw RegisterFontError(errorMessage: "Could not create font data provider for \(url).")
}
let font = CGFont(fontDataProvider)
var error: Unmanaged<CFError>?
guard CTFontManagerRegisterGraphicsFont(font, &error) else {
throw error!.takeUnretainedValue()
}
}
Apple Instruments :

After investigation of the parameters of the CTFontManagerRegisterGraphicsFont I found that error parameter is type of UnsafeMutablePointer<Unmanaged<CFError>?>?. And the main issue is connected with Unmanaged type.
So what is Unmanaged type.
An Unmanaged wrapper, like an Optional wrapper, provides a layer of
safety between your code and a potentially nasty crash. The
Unmanaged type stores a pointer whose memory is not controlled by
the Swift runtime system. Before using this data, you take
responsibility for how this memory should stay alive.
And what is UnsafeMutablePointer
UnsafeMutablePointer provides no automated memory management or
alignment guarantees. You are responsible for handling the life cycle
of any memory you work with through unsafe pointers to avoid leaks or
undefined behavior.
So as it possible to understand we should fix my code with this few code lines.That will release error after we fetch error description.
public static func register(from url: URL) throws {
guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {
throw RegisterFontError(errorMessage: "Could not create font data provider for \(url).")
}
let font = CGFont(fontDataProvider)
var error: Unmanaged<CFError>?
guard CTFontManagerRegisterGraphicsFont(font, &error) else {
let message = error.debugDescription
error?.release()
throw RegisterFontError.init(errorMessage: message)
}
}

Related

Creating a low-s ECDSA signature in iOS

I need to interact with Hyperledger Fabric in an iOS application, and I've run into a problem when creating the proposal signature. Fabric requires low-s ECDSA, but I can't find a way to specify that in Apple's crypto functions. Without specifying low-s, my calls fail about %50 of the time, when S is higher than R.
My signing code is pretty simple:
static func sign(data:Data, withPrivateKey:SecKey) throws -> Data {
var error: Unmanaged<CFError>?
guard
let signature = SecKeyCreateSignature(
withPrivateKey,
.ecdsaSignatureMessageX962SHA256,
data as CFData,
&error
) as Data?
else {
throw error!.takeRetainedValue()
}
return signature
}

Go-Ethereum iOS cannot unmarshal results

So I'm playing around with go-ethereum in iOS and I'm having quite a bit of trouble trying to interact with a contract deployed to Rinkeby testnet, I'm very new to the whole blockchain technology so any help is appreciated.
All I'm trying to do is access a deployed contract and get the value of a string but the issue I'm having is I get this error when I try to make a call to a bound contract:
Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=go Code=1 "abi: cannot unmarshal string in to []interface {}" UserInfo={NSLocalizedDescription=abi: cannot unmarshal string in to []interface {}}
this is the code I'm using to make the call.
// Declare the error variables
var clientError: NSErrorPointer;
var addressError: NSErrorPointer;
var contractError: NSErrorPointer;
// Get the bindContract from Rinkeby test network.
let client = GethNewEthereumClient("https://rinkeby.infura.io/v3/398ed56d211646faaf010ca183de11f2", clientError);
let contractAddress = GethNewAddressFromHex("0x7259667715d671Ee370d7788647f95Fe7C3B532d", addressError);
guard let contractABI = ReadJsonResourceAsString(fileName: "InboxContractInterface", fileType: "json") else {
print("[ViewController] failed to read the abi json as string.")
return;
}
let boundContract = GethBindContract(contractAddress, contractABI, client, contractError);
// Prepare the callOpts
let callOpts = GethNewCallOpts();
callOpts?.setGasLimit(300000);
callOpts?.setContext(GethNewContext());
// Prepare the results & params interfaces
let results = GethNewInterfaces(1);
let params = GethNewInterfaces(0);
let stringResult = GethNewInterface();
stringResult?.setDefaultString();
try! results?.set(0, object: stringResult);
// Make the call
let methodName = "message";
try! boundContract?.call(callOpts, out_: results, method: methodName, args: params);
// Show results.
print("[ViewController] message call result: " + (stringResult?.getString())!);
And this is my contract's code:
pragma solidity ^0.4.17;
contract Inbox {
string public message;
function Inbox (string initialMessage) public {
message = initialMessage;
}
function setMessage (string newMessage) public {
message = newMessage;
}
}
For anyone that might find the same issue after digging a bit more I found this issue for android: https://github.com/ethereum/go-ethereum/issues/14832
Luckily this is already fixed, so it was totally my fault for not using the latest version.
I was using Geth v1.5.9 so after updating to v1.8.2 it finally worked, not sure which version in-between got fixed tho.

Swift app stops running after an error

My iOS app stops running after a run-time error occurs. I'm catching the error as an exception. I would like the app to continue running to the next steps after error handling. Any advises how to do this?
do {
guard let ps: Element = try! docu.getElementById("product-name")! else { ide = "" }
if ps != nil {
ide = (try ps.text())
}
} catch {
print("error")
ide = ""
}
I think you are overusing the ! (force unwrap) symbol here. It does not deal gracefully with nil values, in fact, it crashes.
I think what you might want to be doing here is
guard
let ps: Element = try? doc.getElementById("product-name"),
let ide = try? ps.text()
else {
print("error")
ide = ""
}
// ide is guaranteed to be valid here
...
Note how if you use try? you do not need to "catch" the error, it will simply return an optional value, nil if the call would raise an exception.
Alternatively you could simply
let ps: Element = try? doc.getElementById("product-name")
let ide = try? ps?.text()
// ide will be an optional value here
If you really don't want to guard/if let...

Firebase: How To Access error object in iOS callback [duplicate]

I used this method very much in Swift 1.2: NSURLConnection.sendSynchronousRequest(:_:_:_) but this is apparently deprecated in iOS9. It still works however but now it uses the new Swift 2.0 Error Handling and I don't know how I will get the error message if it fails, ex. if time runs out.
I know I have to put it into a do-catch and then say try before the metho but I dont know how to catch the error message.
do {
let data = try NSURLConnection.sendSynchronousRequest(request, returningResponse: nil)
return data
}
catch _ {
return nil
}
Before I used NSError and then its description property, but now I have no clue.
Use automatic error variable, and you can cast it to NSError if you wish:
catch {
let nsError = error as NSError
print(nsError.localizedDescription)
}
You can now throw any object inheriting ErrorType, and provide custom handling in the catch sentence. You can also cast the error to NSError to access localizedDescription for handling third party errors.
Casting an enum ErrorType will produce a NSError with domain equal to the enum name, code equal to the enum value and an auto-generated localizedDescription with the following format:
The operation couldn’t be completed. (DOMAIN error CODE.)
For example, the following code:
enum AwfulError: ErrorType {
case Bad
case Worse
case Terrible
}
func throwingFunction() throws {
throw AwfulError.Worse
}
do {
try throwingFunction()
}
catch AwfulError.Bad {
print("Bad error")
}
catch let error as NSError {
print(error.localizedDescription)
}
Will print
The operation couldn’t be completed. (AwfulError error 1.)
Despite the question title specifying Swift 2, this answer is for Swift 3.
As #redent84 points out, since Swift 2 an Error object may be a home-made one. Here's a method I wrote to analyze and print the default error object available in a "catch" statement that doesn't specify any specific error type:
// Method to print an unknown Error type object to the system output.
static func printCaughtError(_ unknownError : Error) {
let objectDescription = String(describing: unknownError)
let localizedDescription = unknownError.localizedDescription
if localizedDescription != "" {
if localizedDescription.contains(objectDescription) {
print(localizedDescription)
return
}
if !objectDescription.contains(localizedDescription) {
print(objectDescription + ": " + localizedDescription)
return
}
}
print(objectDescription)
}
Then you can call it like this:
catch {
printCaughtError(error)
}
How to get the error message that is inside userInfo:
let errorMessage = (error as NSError).userInfo["message"] as? String

handling error using xcode 7.0 beta in asynchronous block

I am trying to validate different errors while downloading text files from AWS S3, and with the next piece of code:
... above here function receiving String parameters ruta, archivo, archivoLocal
let directorioURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first! as NSURL
let archivoURL = directorioURL.URLByAppendingPathComponent("b\(archivoLocal)")
let downloadRequest = AWSS3TransferManagerDownloadRequest()
downloadRequest.bucket = ruta
downloadRequest.key = archivo
downloadRequest.downloadingFileURL = archivoURL
let transferManager = AWSS3TransferManager.defaultS3TransferManager()
let task = BFTask()
let executor = BFExecutor.mainThreadExecutor()
transferManager.download(downloadRequest).continueWithExecutor(executor, withBlock: { (task) -> AnyObject! in
if task.error != nil {
if task.error.domain == AWSS3TransferManagerErrorDomain {
self.processDomainErrorType(AWSS3TransferManagerErrorType(rawValue: task.error.code))
} else {
self.processError(task.error)
}
} else if task.result != nil {
do {
let mytext = try String(contentsOfURL: archivoURL, encoding: NSUTF8StringEncoding)
self.processResult(mytext)
} catch let urlerror as? NSError {
self.processError(urlerror)
}
}
...
I am getting the error:
Invalid conversion from throwing function of type '(_) throws -> AnyObject!' to non-throwing function type '#convention(block) (BFTask!) -> AnyObject!'
I obtained the "do { try } catch" syntax from https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID10
I can remove the error by replacing the catch clause with:
} catch _ {
self.processError(NSError(domain: "String-ContentsOfURL Error", code: 100, userInfo: nil))
}
Of course this way I will never know the real cause why ContentsOfURL could be failing.
All I can figure out why this error happens is because this syntax is valid only for OS X apps and for iOS the error handling guide at
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014097-CH42
allows only the second syntax unless you own the object throwing the errors from an enum structure of ErrorType type, which is not the case since I want to catch the NSError from String object, contentsOfURL function.
I hope someone could guide me through this, maybe being XCode 7 a beta, the catch syntax is still incomplete or maybe I should not matter about the reason why this function fails, but I think it is important to determine what is making this function fail and if it could be traced and fixed before reaching the do-try-catch clause.
Additionally to the above error, I am getting a warning in the task variable assignation line to BFTask() saying that "Initialization of immutable value 'task' was never used". I think this is a bug with this beta version that it doesn't include the pattern to acknowledge that the variable task is being used in the asynchronous block. I'd appreciate a lot some confirmation about this and if I just need to ignore it.
By the way, the only reason I am using XCode 7 beta is because my client wants to evaluate the app before acquiring their apple membership.
Apple replaced NSError with ErrorType in Swift 2.
Replace your own explicit usage of NSError with ErrorType and you don't get this type of compiler errors.

Resources