Get a CGImageRef from an IKImageView in Swift - macos

I'm trying to get the image associated with a view but Xcode returns me an error. Here is the code:
#IBOutlet var imageView: IKImageView // Link to the image view.
func saveImage() {
var newImage: CGImageRef = imageView.image() // Line with an error.
}
I have a awakeFromNibfunction to set the image in the view. The code above returns me 'Unmanaged<CGImage>' is not convertible to 'CGImageRef'.
I know that types are optional in Swift but I don't understand why I get this error, the IKImageView Class Reference clearly said that get IKImageView's image return a CGImageRef.

This has to do with the bridging of Objective C APIs into Swift. The Swift versions of an API have been bridged (mostly automatically, I believe) by converting the original Objective C headers into a Swift version. In many cases, the conversion can work out what kind of value you're going to get back, and therefore in Swift you get a "normal" type that you can use as you'd expect.
However, the conversion is still a work in progress. In this case, what you're seeing is a type used to help you manage memory manually when the conversion process doesn't know whether you're going to get back an object that's been retained for you or not, because the API doesn't have the conventional annotation that it could use to figure it out.
The Unmanaged type effectively says "you have to tell me what to do with the contained value to get the memory management right". As soon as you get an Unmanaged value, you should call either one of its two methods:
takeUnretainedValue()
takeRetainedValue()
...depending on whether the object you get back was a "+0" or "+1". So, you're expected to do something like:
var newImage: CGImage = imageView.image().takeUnretainedValue()
And as soon as you've done that (which you should do pretty much immediately), you've given Swift enough of a hint that it can now appropriately manage the object correctly with ARC, and got yourself a valid reference of the right type.
This is touched on briefly at the end of the "Swift Interoperability in Depth" WWDC video from this year.

Look at the image() method in the new version of the IKImageView reference that shows Swift declarations and you'll see it returns an Unmanaged<CGImage>!. That means that ImageKit isn't set up such that the compiler can automatically infer CoreFoundation memory management semantics on its API. (This affects both Swift translation and ObjC implicit ARC bridging.) It should, so that'd be a good bug to file.
The Swift type Unmanaged<T> is how you interact with CF types when the compiler can't automatically infer their ARC behavior. To get at the underlying type, call either takeUnretainedValue() or takeRetainedValue() — you have to choose which depending on whether the API you're calling is known to already be retaining the value it returns. Exciting guesswork! (Again, eliminating guesswork would be a good bug to file.) You can read more about this in Using Swift with Cocoa and Objective-C.
Anyway, in this case you can probably expect that IKImageView is not incrementing the retain count of the CGImage when providing it, so you can unwrap the Unmanaged like so:
var newImage: CGImage = imageView.image().takeUnretainedValue()
Also note you don't need the Ref suffix when working with CF types in Swift. (CGImageRef is a typealias to CGImage.) Swift lets you work with CF types as if they're Swift objects (instead of as C pointers to opaque C types).

Related

delegates in ruby explained from a Cocoa developer background

I really hope someone can answer this one. I think I am definitely not the only one confused about this and I wasn't able to find anything that clearly explains this concept.
My understanding of the delegation pattern comes from studying the Cocoa framework. To me, the Cocoa implementation is very clear. But I am having a very hard time understanding it in Ruby (standard library's Delegator, SimpleDelegator vs. ActiveSupport's Delegate). It makes little sense to me. Mostly because one is type safe the other is duck type. You can see my point already, but allow me to expand... Here is my summary of how to use the delegate pattern in Cocoa:
Our "ingredients" are: 2 classes, A and B and a protocol, which is Cocoa for a pre-defined set of methods to use for delegation.
The implementation of the pattern is basically as follows:
A defines the set of methods to delegate to B.
B's delegate is set to be A
=> B can now call delegated methods like so: #delegate.send(a_delegated_method)
What I am not tying together is the fact that Ruby uses duck typing, so you can send any method call to any object, right? So using the pattern I just explained, as long as the 2 objects are in the same domain you can say while in A #b.send(:a_delegated_method) and vice versa while in B #a.send(:another_delegated_method).
Could it be that the point with delegates in Ruby is where the delegated method is defined? Meaning that we send from within class A to property #b (#b(:delegated_method)) a :delegated_method defined within A itself?
Hope this isn't too confusing. I myself am confused about why delegates even exist in a duck typing language and what the differences are between Delegator, SimpleDelegator and ActiveSupport's Delegate.
It isn't clear to me that you have understood how delegation works in Cocoa. It is true that the common variety of the delegation pattern in Cocoa involves a protocol, but that's just a way of quieting the compiler.
So let's talk first about quieting the compiler. You can't send the woohoo message to an object in Objective-C unless one of two things is true:
The compiler has reason to believe that this object might respond to the woohoo message.
The compiler is made to suspend judgment.
Nowadays, the first approach is usually used - that's what a protocol is for. But this was not always the case. It used to be that delegation depended mostly on informal protocols. And there still are informal protocols in Cocoa. The idea is that either the method is injected into NSObject by a category, or else you are careful to type the object as id so that it can be sent any message at all.
Now let's talk about dynamism. The reason informal protocols are no longer used is that a feature was introduced allowing protocols to declare optional members. But dynamism is still needed! We may satisfy the compiler, one way or another, but at runtime we have to make sure that it is safe to send a certain message to a certain object. Your app delegate may adopt UIApplicationDelegate, but Cocoa is not going to send it the applicationDidBecomeActive: message unless your app delegate class implements applicationDidBecomeActive: - if it did, you'd crash, and that wouldn't be very nice.
Moreover, if you can just get past the compiler, you can perform delegation in Objective-C even more dynamically than that, as explained here:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html
The idea is that we go right ahead at runtime and send the object the message anyway! If a message arrives that Object A can't handle, it can see if Object B handles it. If it does, it passes the message along to Object B. So we might not crash after all!! I use that approach in one of my apps:
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([self.originalDataSource respondsToSelector: aSelector])
return self.originalDataSource;
return [super forwardingTargetForSelector:aSelector];
}
In that code, I'm saying that if a message arrives and I can't handle it, I should try to get it sent on to another object, called self.originalDataSource.
If you think about it, that is almost identical to Ruby delegation. I have a helper object, and messages that I can't handle are passed on to it.
Another common use of this pattern is when wrapping a Cocoa collection. You can't subclass, say, NSArray, because it's a class cluster, so the proper approach is to wrap it. You then just forward everything to the NSArray, and presto, you are duck-typed as an NSArray! You look like an NSArray as far as your methods are concerned. Then you introduce some difference in behavior, and now you are duck-typed as a customized NSArray.

Xcode:(user defined runtime attribute)Range with minus value. Alternative?

I made a custom UITextField with an additional user defined runtime attribute validRange, which I can set in the storyboard view.
I use this property to check in the EndEditing method to validate the new set text.
I works all fine, till I had to set a valid range from {-100,100}
As NSRange uses NSUInteger, there are no minus values possible.
What is the best way to still make this happen?
Would it be acceptable if I use CGSize instead of NSRange?
Updated Content
Xcode only gives me the following choice of data types for the user defined runtime attributes:
This means I cannot define a new struct to create a CustomRange with NSInteger.
As Point,Size are both {NSInteger,NSInteger} data types, I thought about using them. But this would be certainly a misuse, so I am wondering if someone knows a better solution, as misusing Point or Size to get this to work.
As another workaround I could user String, which I manually would split up in a method of the custom UITextField, but then there is no type safety.
Then I would suggest you to define two NSNumber properties with suitable names to represent NSRange value instead of abusing CGSize as using CGSize confuses other readers/programmers as we there is a saying, we code for others not for ourselves.
And there is a NSNumber class method as follows
+ (NSNumber *)numberWithInteger:(NSInteger)value
which allow you to wrap signed integer value as you intend.

How to re-write Objective C Delegate Method in Swift

I'm trying to re-write a cocoapod's Objective-C delegate protocol in Swift. The cocoapod is MZTimerLabel and I'm trying to notify my View Controller when the timer has finished. Xcode tries to layout the correct syntax for me but I cannot quite understand what is is asking for. For example, when I am reading the example method I can't discern when it says timerLabel whether that means to type 'timerLabel' or if `timerLabel' is a placeholder for my instance of the MZTimerLabel.
It looks like the protocal is telling me to call on MZTimerLabel and then tell it what instance in my view controller to listen for (my instance is called brewingTimer, but I can't get the Swift Syntax right. Perhaps I should declare brewingTimer.delegate = self in my ViewDidLoad()?
-(void)timerLabel:(MZTimerLabel*)timerLabel finshedCountDownTimerWithTime:(NSTimeInterval)countTime {
//time is up, what should I do master?
}
My Swift attempt:
MZTimerLabel(timerLabel(brewingTimer, finshedCountDownTimerWithTime: 5)){
//What I want to do when the timer finishes
{self.startTimer.setTitle("Ok!", forState: .Normal)
}
I get the error "use of unresolved identifier 'timerLabel'"
I'm learning programming more or less from scratch with Swift as my first language so I'm constantly having to learn to read code "backwards" in Objective C to translate it over to Swift. Also, I don't understand what "countTime" is. I've read through all of the Swift documentation and have looked through guides for method's in Objective C, but seeing an example of an actual Objective C method written in Swift would be very helpful.
Your delegate function becomes in swift as
func timerLabel(timerLabel: AnyObject!, finshedCountDownTimerWithTime countTime: NSTimeInterval){
self.startTimer.setTitle("Ok!", forState: .Normal)
var yourTimerLabel = timerLabel as? MZTimerLabel //Downcast to MZTimerLabel
//Now you can use yourTimerLabel as instance of MZTimerLabel
}
Implement this in your viewController where you want to get notified.Also conform to protocol.
Here timerLabel is instance of MZTimerLabel
Also import your protocol to Swift Bridging Header

object c runtime associate object

associate object tutorial
"The tutorial link gave me a clear concept of object-c runtime associate object"
After reading the example code below, I have a small question.
- (void)setAssociatedObject:(id)object
{
objc_setAssociatedObject(self, #selector(associatedObject), object,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)associatedObject
{
return objc_getAssociatedObject(self, #selector(associatedObject));
}
If your using ARC in iOS, do we need to add memory handling by ourselves?
Thanks in advance
The call you have to objc_setAssociatedObject will cause the object to be retained — that's the OBJC_ASSOCIATION_RETAIN_NONATOMIC part. That being the specified behaviour, it'll also automatically be released when the object with which it is associated is released.
So you don't need to do any further memory handling whether you're using ARC or not (subject to the caveat that if you wanted this to act like a copy property, you'd obviously need to add copying, which would look different under ARC and non-ARC).

How to use IProjectionBuffer in MEF without creating editor instance?

I am trying to create a Visual Studio extension which handles a multi-language content type. Much like some mvc-templates and Django or ASP.NET which a certain part of the code is in another language.
I know that I should use Projection and I already checked Django for Visual Studio extension but the solution there includes creating a Language Service and going to the trouble of creating all bits and pieces related to a code editor. Here I am trying to achieve the same goal just by using MEF.
I know that you can use IProjectionBuffer CreateProjectionBuffer() to create a projection but the question is how to replace the current TextBuffer with the created one and when is the best time to do it.
Also one may expect that if he specifies a base definition of type "projection" like this:
[Export]
[Name("Whatever")]
[BaseDefinition("code")]
[BaseDefinition("projection")]
internal static ContentTypeDefinition WhateverContentType = null;
the received TextBuffer in providers to be of type IProjectionBuffer (after all IProjectionBuffer is inherited from ITextBuffer). Which are not and it seems that a projection base definition has no effect what so ever.
So if I want to rephrase my question in a tldr version:
How and when do you apply an IProjectionBuffer to current view (using MEF and without creating an editor instance)?
So if I understand your question correctly, the answer is "you don't." A IWpfTextView is bound to a implementation of ITextBuffer (or a derived type, like IProjectionBuffer) at creation time, and can't be changed. Even if you could, many other extensions and language services would be most surprised by this and would probably crash.
To address your second question about content types: simply declaring you have a base content type of "projection" doesn't make you a projection buffer. All that really states is you might be creating projection buffers of that type, and when you do you want some extra ITagger support so taggers project through to the source buffers as you might expect them to.

Resources