Sunday, October 23, 2011

Building and Submitting iOS Apps built using user created static libraries

 

Here are my notes on getting an iOS app submittable to Apple’s app store, which includes an interesting “welcome back to header files” experience. Resolving all the issues required a fair amount of searching and futzing, so I thought I’d put together a synopsis and share:


Step 1: Compiling a project referencing a static library I created.

Background: I’m building a suite of apps centered on pdf file display, using the vfr pdf reader framework -- the developer, Julius Oklamcak, characterizes it a basic framework, but I found it both robust and easily configurable to fit my needs.

The first task was to build a library consisting of the vfr pdf reader code so that the code would be factored appropriately. Using this approach, any bugs showing up in the pdf reader require only one code change to fix all the books.

I used CarbonFive’s blog post on building and using static libraries to perform the setup.

It took a bit of tweaking to get the library incorporated/recognized by the dependent projects, and, sadly, one of those tweaks came back to bite me later.

The primary change was to put all the projects in a single Xcode workspace so that the library was readily available to the dependent project (apps). Workspace creation, followed putting the library in the frameworks folder, and making the .h files public, made the .h files visible to the dependent project.

After these changes, the dependent project could

compile and run, both on the simulator and on my test device.

 

Step 2: Archiving the Project

However, when I went to archive the app (a precursor to submission), the necessary .h files suddenly could not be found.

There didn’t seem to be any “build level” way around this -- meaning that I couldn’t find a way to eliminate this error that just entailed changing some configuration files. The only solution I could find was to move copies of (or links to) the actual header files being referenced.

Upon further consideration this appears to be an artifact of the build environment/ObjectiveC language, since even the foundation frameworks are packed with their header files (see below)


FrameworkContents

 

Step 3: Validating the Project

At this point the archive could be created without errors, but when I tired to validate and submit I got the following

"[projectname] does not contain a single–bundle application or contains multiple products. Please select another archive, or adjust your scheme to create a single–bundle application."

This was a quick issue to fix -- the answers appearing on stack overflow

Archiving project in XCode incorrectly creates multi-application bundle

The fix required changing the file visibility (back) from public to project. Changing file visibility is most easily accomplished by moving the .h files to the appropriate part of the Copy Headers section of the Build Phases tab for the target -- I will admit that this approach was advocated it the CarbonFive blog, but it didn’t appeal to my (Java tuned) sensibilities.

H file movement

Step 4: Submitting the Project

The fun wasn’t quite over, since an attempt to submit the app resulted in the response

No suitable application records were found.

After setting up the signing appropriately per Apple’s guidelines http://developer.apple.com/ios/manage/distribution/index.action

-- somewhat obscurely located here

Apple directons


(BTW am I the only  one finding it frustrating that Apple’s documentation hasn’t been fullly refreshed to reflect the Xcode4 UI?)

and reading stack overflow again,

illed out the questionnaire and I was able to submit and upload successfully.

Hope this short walkthrough proves useful.



Monday, August 15, 2011

Commenting in html, tpl.php etc.

I came across a very nice commenting convention in the drupal zen theme template files:

They close all of the class and id marked sections with

<!-- /.{classname} -->

or

<!-- /#{idName} -->

 

e.g.,

<tr class="genesis-page-header-row">

is closed  with

</tr><!-- /.genesis-page-header-row -->

 

This is nice enough in helping you to keep track of what's going on when editing the code. However, it is invaluable in understanding what might have gone wrong when examining pages in a "modern" inspector.

For example, here's how that section looks in Safari 5.1:

Drupal image upload

making it clear that the you and the browser both agree on the <tr> being terminated by this </tr> (if you and the browser don't agree, it probably indicates that something has gone awry).

 

 

Sunday, June 26, 2011

Debugging Drupal Access Denied

I just finished debugging an Access Denied problem in Drupal, and wanted to add a couple more tips to those in Simon Lane's Drupal Permissions Issues: A Debugging Checklist

First: assure that the users unable to access the content have been given the appropriate roles.

Second: check the permissions of a role that can access the content relative to one that can't -- the following query works in MySQL and is both quicker, and more accurate, than a visual check.

select permission, module from role_permission 
where rid = 5
and permission not in
(select permission from role_permission where rid = 4)

Where "5" is id of the role that has access, "4" is the id of the role being denied access.

Third, and most obvious: assure that the "inaccessible" content has been published. This was the source of my particular problem (doh!).


I echo the words of many posters, when I say "It would be nice if Drupal would log the reason for denying access. It would save everyone a lot of time"

Thursday, April 28, 2011

Drupal 7.0: broken image preview

I recently decided to use Drupal for one of my projects, since all reports are that it is both well designed and relatively easy to extend.

I'm just getting it set up locally on my MacBook Pro (10.6.7) and ran into a problem with previewing uploaded images: nothing was getting displayed for the preview, even though the images would display fine when saved.

The following errors were being logged.

Access denied

The solution, took a while to find, but was relatively simple: changing the upload location to Public files (see below), cured the problem.

Drupal image upload

(Switching it back recreated the problem) -- seemed worth sharing.

 

Monday, April 4, 2011

CoreData != CoreObjects

I ran into a situation last week that had me (proverbially) tearing my hair out.

I was trying to call methods on an object stored using CoreData and the calls just WOULD NOT WORK. The reason was not obvious, and even the simplest method dispatch was failing: the debugger showed the objects as being of type NSManagedObject rather than the expected GTGItemLocationList, even after casting the local var as a (GTGItemLocationList *).

Managed object

 

Rather than continue, I decided to spend some time reading Pro Core Data for iOS since, in any case, I felt that my understanding of Core Data was suboptimal. Pro Core Data is an excellent resource and greatly improved  my understanding of the Core Data framework. I decided to stop trying to treat my GTGItemLocationList as an instance of the GTGItemLocationList class, and instead use the NSMutableArray pattern described in the book.

I  went back and coded up what I needed in about an hour.



Everything has been going well since then, and I thought I'd write this up as a cautionary tale about CoreData not providing objects in the manner expected. However, after digging a bit more, I found that this wasn't quite accurate. After all, the method which was throwing this exception was itself a method on an object stored by CoreData, and the dispatch was to the expected class/method combination. The pattern of accessing the object was different: rather than directly through an accessor, it was via an objectEnumerator on NSArray. The object returned using this technique was a GTGItem manipulatable via conventional OO techniques as expected (and appreciated).

Working item

I will admit that I haven't determined what's going on here. I think that the moral of the story is that in exchange for CoreData's simplicity and ease of use,* you might find yourself exploring a corner case that exhibits unexpected behavior. In retrospect, the GTGItemLocationList is completely superfluous. Eliminating this class would improve functionality and move me back into the CoreData's core use cases, reinforcing one of my basic iOS heuristics: If it is very hard to do, your first reaction should be "what built in function am I ignoring that would make this easy?".

For completeness -- I'm not the only one who has seen this problem, see here, and here -- none of the suggestions cured my problem

_____________________________________

 *I mean this sincerely: the Pro Core Data highlighted the built in! CoreData data migration capabilities. Given how much time the industry spends planning/managing/performing data migration projects, any capability in this space is welcome.

Friday, February 4, 2011

python, Mac, MySQLdb "wrong architecture"

I thought I'd post this tip since I had a few false starts following other pointers I found on the web -- I'd like to save others the wasted effort.

The error (MySQLdb "wrong architecture") IS because of a mismatch between the version of python and the version of the OS that you're running.



If you are trying to import MySQLdb into Python and getting a "wrong architecture" error message, try the following:

First, determine the version of your OS by typing

uname -a

into a shell (Thanks OSXDaily)



Then install a current version of Python that matches this architecture from python.org, reinstall MySQLdb and see if it works.

This is all that it took for me to be up and running, and is (relatively) painless.

Note: be sure that your scripts point to the newly installed version at /usr/local/bin/python, rather than the system version at /usr/bin/python