Is IOS 5 UIDocument subclass backwards compatible? - ios

To support iCloud, we're encouraged to use a UIDocument subclass. If I define a new subclass, set the project target version to 3.0, and test using for iOS 5 before using my new subclass, will the code work on iOS 4 or does linking in a subclass break backwards compatibility?

UIKit can be weak-linked, but the results would be undefined if you tried to initialize a UIDocument or UIDocument subclass. You would need something like:
if (NSStringFromClass(#"UIDocument"))
{
...
}
That would make it totally useless for your purposes. So the answer to your question is no, any code involving UIDocument would not run, but you could put conditional checks around such code. You're better off finding an alternative method for saving data.

It will need to link with UIDocument in order to understand what subclassing UIDocument actually means. For example, if you have class Bar which subclasses Foo, and Foo has method 'doBaz', you can call 'doBaz' on a Bar instance, but if the linker doesn't know Foo, it doesn't know Bar can doBaz.
You may be able to do a weak link though. There was a similar situation when iOS 4 came out, with iAds not being available in iOS 3, which was the best on iPad at the time.

Related

Xcode won't let me use NSObject's init() function for UIView

It might be very similar to this still-opened question: Xcode 10 beta2: Cannot invoke initializer for type 'UIView' with no arguments
Issue:
Cannot invoke initializer for type 'UIImageView' with no arguments
But kindly please give me a chance to ask this. I have a project that is written in Swift 4.0 previously and suddenly Xcode won't let me make a UIView object with NSObject's init() method. Just all of a sudden.
What I already did:
I switched back to a working commit, and boy, project won't still compile.
Of course I tried compiling my other projects and of course they compiled while having so many views constructed with UIView().
Tried search for answers, but then again the question linked above does not have an answer.
Currently doing a comparison between this project's project settings against a new project's.
What I want to ask and want to know:
I need to know, cause this is quite bothering, why this happens.
Is this a configuration error in Xcode? But I somehow doubt that because I already switched to a working commit and it still has compile-time errors.
Please don't tell me to use UIView(frame: CGRect) constructor, as I have hundreds of UIView() code, and similar code.
What I do know:
Where does UIView.init() come from?
Keep in mind that UIView is an Objective-C class, and Objective-C is
not Swift. None of the rules about designated and convenience
initializers and the rules of their inheritance exist in Objective-C —
a fact that can sometimes cause significant trouble when using those
classes in Swift. That said, in effect, UIView's init() is a
convenience initializer that calls init(frame: .zero).
Thanks!
To close this thread/question, I'll add an answer.
I wasn't the one who solved this. This project, if not mentioned in the question, is merely a side project, from a remote/freelance work. I was actually, if not mentioned above too, migrating the project to Swift 4.2. Along the way, this issue came up. I didn't bother to rename all the pieces of codes to be renamed during the update. Long story short, I gave up on this task for a bit, but someone in the company decided to solve it.
The solution is: finish the migration first. Just rename all the stuff that is needed for Swift 4.2, and update the pods as well. That's it! :) I hope this helps people in the future.

How to wrap existing iOS code in a new Appcelerator module?

This seems like a basic request, but I can't find the answer to it anywhere. I want to wrap some existing iOS code that I wrote, in a Appcelerator module. That's it. Important points:
I am NOT wrapping a pre-existing 3rd party iOS SDK.
I wrote the iOS code being wrapped.
Code is verified as working within xcode.
There are no .a files. There are 2x .h files and 2x .m files though.
There are no UI elements in the iOS code as it is only designed to connect the native bluetooth hardware to the app.
I have created a generic appcelerator iOS module project, built it, and successfully called the generic ID function within my app.
I cannot figure out how to successfully edit the generic module so that it utilizes my code. Every attempt results in it refusing to compile, and it's maddening.
I do not have access to Hyperloop.
Once I can successfully build the wrapped module, I would call an initialization function which triggers a native bluetooth hardware search. Once connected, there are functions within the module to send commands to the hardware and receive data back. This is the official documentation I've followed so far:
http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Module_Quick_Start
That helped me build the blank module, include it in the app, and ensure that it worked by calling the built in test property. From there it stops short of actually telling me what I need to know. These are the closest things I've found so far, while still not being what I need:
http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Module_Project-section-43288810_iOSModuleProject-AddaThird-PartyFramework
appcelerator module for existing ios project sdk
Heck, I still don't even know if I can do this within studio or if I have to edit the generic module in Xcode. Help! :) Many thanks in advance.
so first of all, this is not best practice and will cause possible problems in the future when the SDK changes and your module still relies on outdated core API's.
Regarding your question, you could either create a new component that subclasses the existing class, e.g.
class TiMyModuleListViewProxy : TiUiListViewProxy {
}
and call it with
var myList = MyModule.createListView();
or you write a category to extend the existing API with your own logic, e.g.
#interface TiUIListViewProxy (MyListView)
- (void)setSomethingElse:(id)value;
#end
#implementation TiUIListViewProxy (MyListView)
- (void)setSomethingElse:(id)value
{
// Set the value of "somethingElse" now
}
#end
I would prefer the second option since it matches a better Objective-C code-style, but please still be aware of the possible core-changes that might effect your implementation in the feature. Thanks!

Auto-implement Swift protocol methods in Xcode

I just started with the swift language and coming from java it looks great so far.
But I'm really missing something:
Eclipse had this great feature that when I added "implements XYZ" it provided me a function to automatically implement the necessary function stubs. This is a huge timesaver.
Xcode doesn't seem to have this feature, or am I missing something?
I found the accessorize plugin, but this seems only to work with Objective C..
Is there a solution?
PS. I'm using Xcode 6.1.1
NB: This answer is true for Xcode before version 9; in Version 9 Apple added the ability to automatically fix up missing protocol methods; see Guy Daher's answer.
I just created an iOS project, and headed into my UIViewController.swift file. There I declared that it implemented UITableViewDelegate:
class ViewController: UIViewController, UITableViewDelegate {
Now when I go into the body of the class, and start typing "tab...", I see the appropriate autocompletions:
Hitting Enter then inserts the function stub, with the cursor placed ready to code.
That's just the way Xcode autocompletes protocols (or inherited class methods.) If you want to do all of them at once, I don't think it's possible, sadly. But you can always Cmd-click or Option-Cmd-click (which uses a secondary editor window) on the protocol name to jump to its definition, which is basically a list of all its methods you can copy and paste into your code. You'd need to tidy up a little from there, but not much.
Xcode 9
Xcode 9 now supports conforming to protocol methods via a "fix it". It will automatically fill the missing methods for you. This was announced in WWDC 2017.
Update: This doesn't seem to work for protocols defined by you, unfortunately.
Xcode 9, takes care of implementation of mandatory methods of Swift Datasource & Delegates.
Look at these snapshots, with example of UICollectionViewDataSource:
Indicating warning to implement protocol methods:
By clicking on 'Fix' button, it has added all mandatory methods:
Alternate Option:
You can use a keyboard short key: Ctrl + Option + Command + F to fix all issues at once.

How can I Quick Look custom objects with Xcode 5 visual debugger?

Xcode 5 has a great new feature where you can hover over a variable name and get a visual representation of a UIColor, UIImage, or even UIBezierPath.
I vaguely remember a comment at WWDC where developers could either conform to some protocol or override some methods on any NSObject subclass in order to participate in this new debugging feature. I would love to add this to a bunch of my model objects to help me debug. Anyone know whether this is a real thing yet, or even if they hinted at it in a future release?
Unfortunately, Apple refers to this feature as "Quick Look" and since they have another technology called "Quick Look" my search results are very noisy and I can't find anything helpful.
This is a new feature in Xcode 5.1, and the documentation on it can be found here. In a nutshell, you override -(id)debugQuickLookObject and return an OS type that already supports Quick Look, e.g. UIImage or NSAttributedString (full list of types in documentation):
- (id)debugQuickLookObject
{
UIImage *image = [...];
// Drawing code here
return image;
}
For Swift:
There are a few options as of writing, none ideal:
Conform to CustomPlaygroundQuickLookable, but that only works in Playgrounds (and requires Xcode 7/Swift 2).
Use the same method as for Objective C. This requires your class to be marked #objc (or inherit a Objective-C class) as the caller relies on selectors.
Conform to Reflectable, but that requires you to provide a full custom MirrorType with a bunch of other properties along with the QuickLookObject (and doesn't even seem to work as of Xcode 7?)
Now that 5.1 has been officially released I've released this new blog post on the matter.
To answer your question: Yes, this is indeed a feature available in the new release of XCode (v5.1) and can be used very easily by subclassing an object and returning whatever it is you want to see while debugging in a -(id)debugQuickLookObject method.

iOS GHUnit and Core Data

ers,
I recently integrated CoreData into my existing iOS application. I have previously existing tests written around some domain and network functionality; that now needs to be retrofitted to use CoreData (instead of storing in userDefaults).
I have GHUnitIOS.framework included in my project. However, all my tests are failing because the TestAppDelegate knows nothing about CoreData's managedObjectContext. For reference as to what I'm seeing:
[GHUnitIOSAppDelegate managedObjectContext]: unrecognized selector sent to instance
This makes sense - the test app delegate doesn't have managedObjectContext as a property. I'd love to add it, but since I only have access to the header files when using the framework, I can't really modify it for my needs. I could download the GHUnit source and modify the implementation files, but I'd rather not do that if there's another option.
How have others solved this problem? IE, how can I fix my tests to support CoreData using GHUnit?
Much thanks.
I had this issue before. GHUnit testing framework uses its own app delegate. So calling the delegate does not call the code you wrote within the app delegate, and its behavior can be erratic.
Generally speaking you should always handle calling your managedObjectContext(s) in a singleton that is not your app delegate. Recently I switched to GHUnit from OCunit and had to abstract all the of that functionality into a different class. It was a pain, but worth it.

Resources