Downcast from AnyObject to UIImage[] - Swift - uiimage

I'm trying to convert the results of a valueForKeyPath into an array of UIImages. When trying to do it I get met with this error
Undefined symbols for architecture i386:
"TToFC9TableView19TableViewControllers6photosGSqGSaCSo7UIImage", referenced from:
__TFC9TableView29JustPostedTableViewController11fetchPhotosfS0_FT_T_ in JustPostedTableViewController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here's my attempt at the code in swift:
The propertyListResults is an NSDictionary, and the parameter in valueForKeyPath is a String
var photos : AnyObject = (propertyListResults as AnyObject).valueForKeyPath(flickrFetcher.FLICKR_RESULTS_PHOTOS)
self.photos = photos as? UIImage[]
And the working Objective-C version of the code is
NSArray *photos = [propertyListResults valueForKeyPath:FLICKR_RESULTS_PHOTOS];
self.photos = photos

If you run swift-demangle on "__TToFC9TableView19TableViewControllers6photosGSqGSaCSo7UIImage__" you get:
#objc TableView.TableViewController.photos.setter : (ObjectiveC.UIImage[])?
That means that the linker is not finding a setter for photos on TableViewController. It seems that you are using a TableViewController instead of your own subclass that has a photos property.
Also, photos as? UIImage[] returns an Optional because it is possible for it to fail. You should do the following:
if let images : [UIImage] = photos as? [UIImage] {
self.photos = images
}
This checks if photos can be converted to [UIImage]. If it can, it assigns it to self.photos
Edit: Updated UIImage array syntax to the new array syntax in the beta 3

Related

Ambiguous use of ‘subscript’ error when importing AVFoundation

Using Xcode 7.2 and Swift 2.1.1
I am retrieving data from a .plist file
The file contains data for a series of quizzes. The data for the quiz to be retrieved consists of an array of 12 questions and a corresponding array of 12 multiple choice options (4 members each).
var quizId = “”
var questions:[String] = []
var answers:[[String]] = []
The quiz id is passed in a segue from the previous view controller. Then the data is retrieved in ViewDidLoad.
let path = NSBundle.mainBundle().pathForResource(“quiz id”, ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)
questions = dict!.objectForKey(“Questions”)![0] as! [String]
answers = dict!.objectForKey(“Answers”)![1] as! [[String]]
The code works perfectly well until I try to import AVFoundation, when the last two lines throw the ambiguous use of ‘subscript’ error.
This is because importing AVFoundation brings up new subscript definitions (namely AUAudioUnitBusArray, thank you Martin R.) and it confuses the compiler which doesn't know what type is dict!.objectForKey(“Questions”) anymore (it is indeed inferred as AnyObject after the import, instead of NSArray).
The cure is to safely help the compiler to know the type, for example by doing a downcast with optional binding:
if let questions = dict?.objectForKey("Questions") as? NSArray {
print(questions[0])
}
or even better:
if let questions = dict?.objectForKey("Questions") as? [String] {
print(questions[0])
}

createFileAtPath not accepting NSURL anymore

let singleImage = "current.jpg"
let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(singleImage)
let fileManager = NSFileManager.defaultManager()
fileManager.createFileAtPath(path, contents: imageDataFromURL, attributes: [:])
createFileAtPath stopped working after upgrade to Swift 2 and now it gives the following error:
Cannot convert value of type 'NSURL' to expected argument type 'String'
Unfortunately NSFileManager has no creation method that operates on a NSURL. In my code I try to avoid String for path usage and this is one of the rare places I still fall back to a path using the NSURL.path property
fileManager.createFileAtPath(pathURL.path!, contents: imageDataFromURL, attributes: [:])

Cannot subscript a value of type nsobject anyobject with an index of type String

I want to get name from google places using address dictionary in my xcode 7 project
Here is my code :
let name = placemark.addressDictionary["Name"] as? String
let city = placemark.addressDictionary["City"] as? String
let state = placemark.addressDictionary["State"] as? String
In otherwords NSObject and AnyObject are not subscript able with a string.
It's not the clearest message.
You might try NSString subscripts or you might not be able to use subscript syntax without more type info to tell Mr. compiler that your objects can respond to subscript syntax

What's the correct syntax of copying a UIViewController?

I would like to copy an instance of a UIViewController.
Something like this:
gOriginViewController = self.copy() as! DiscoveryViewController
Which gives me the runtime error:
Bliss2.DiscoveryViewController copyWithZone:]: unrecognized selector sent to instance 0x7f8b4440cd70'
What's the correct syntax of doing a copy?
UIViewController does not implement NSCopying, and thus cannot be copied using copy(). You can use NSKeyedArchiver to do this:
let data = NSKeyedArchiver.archivedDataWithRootObject(self)
let copy = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! DiscoveryViewController

Undefined symbol in OSX, but standard Apple methods?

I am pretty new to OSX programming, or to the use of ObjC. I've done a fair bit of C en C++ in the past, mainly in combination with VTK.
I am trying to compile a very simple program, where I copied an init method from Apple demo code. I am pretty sure I'm forgetting something. My project is a default Cocoa app, and I made a class MyRoster which for some reason causes linking problems. The output during compilation is the following (if anyone needs more, just say so):
Ld /Users/mark/Library/Developer/Xcode/DerivedData/Rooster-giqzgxqladmwyjepkqehtzkmuvyd/Build/Products/Debug/Rooster.app/Contents/MacOS/Rooster normal x86_64
cd /Users/mark/Documents/Programming/Rooster
setenv MACOSX_DEPLOYMENT_TARGET 10.7
/Developer/usr/bin/clang -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.7.sdk -L/Users/mark/Library/Developer/Xcode/DerivedData/Rooster-giqzgxqladmwyjepkqehtzkmuvyd/Build/Products/Debug -F/Users/mark/Library/Developer/Xcode/DerivedData/Rooster-giqzgxqladmwyjepkqehtzkmuvyd/Build/Products/Debug -filelist /Users/mark/Library/Developer/Xcode/DerivedData/Rooster-giqzgxqladmwyjepkqehtzkmuvyd/Build/Intermediates/Rooster.build/Debug/Rooster.build/Objects-normal/x86_64/Rooster.LinkFileList -mmacosx-version-min=10.7 -framework Cocoa -o /Users/mark/Library/Developer/Xcode/DerivedData/Rooster-giqzgxqladmwyjepkqehtzkmuvyd/Build/Products/Debug/Rooster.app/Contents/MacOS/Rooster
Undefined symbols for architecture x86_64:
"_CalEventsChangedNotification", referenced from:
-[MyTasksCalendar init] in MyTasksCalendar.o
"_CalEventsChangedExternallyNotification", referenced from:
-[MyTasksCalendar init] in MyTasksCalendar.o
"_OBJC_CLASS_$_CalCalendarStore", referenced from:
objc-class-ref in MyTasksCalendar.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The base app compiles fine; the problem is this modified init method:
- (id)init
{
self = [super init];
if (self) {
// Add the receiver as an observer of Calendar Store notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(eventsChanged:) name:CalEventsChangedExternallyNotification object:[CalCalendarStore defaultCalendarStore]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(eventsChanged:) name:CalEventsChangedNotification object:[CalCalendarStore defaultCalendarStore]];
// Create a predicate to use to fetch the events
NSInteger year = [[NSCalendarDate date] yearOfCommonEra];
startDate = [[NSCalendarDate dateWithYear:year month:1 day:1 hour:0 minute:0 second:0 timeZone:nil] retain];
endDate = [[NSCalendarDate dateWithYear:year month:12 day:31 hour:23 minute:59 second:59 timeZone:nil] retain];
NSPredicate *eventsForThisYear = [NSPredicate eventPredicateWithStartDate:startDate endDate:endDate calendars:[[CalCalendarStore defaultCalendarStore] calendars]];
// Fetch all events for the current year
events = [[NSMutableArray array] retain];
[self addEventArray:[[CalCalendarStore defaultCalendarStore] eventsWithPredicate:eventsForThisYear]];
}
return self;
}
My question: why would this not link? The called methods are in standard Apple libraries, so what gives?
Many thanks,
Mark
It looks like you're missing the CalendarStore framework from your project - try adding /System/Library/Frameworks/CalendarStore.framework to your project.

Resources