2013年4月1日星期一

dyld: Symbol not found: _UICollectionElementKindSectionHeader

程序在simulator上没有问题
但在 ios 5.1的device上就报错



实际上是 UICollectionView 的 SupplementaryElement 分 kind,虽然 UICollectionElementKindSectionHeader 是 SupplementaryElement 的一种kind,但使用了 UICollectionElementKindSectionHeader 就导致了错误。


UICollectionElementKindSectionHeader 是 string



NSString *const PSTCollectionElementKindSectionHeader = @"UICollectionElementKindSectionHeader";
NSString *const PSTCollectionElementKindSectionFooter = @"UICollectionElementKindSectionFooter";


iOS应用内打开App Store应用详情界面

用iPhone浏览UC浏览器的“应用商店”时,发现可以直接在应用内打开App Store中的应用详情和下载页面。效果如下:
 
 
        下面来看看怎么实现这个效果吧。
 
        苹果官方文档 "SKStoreProductViewController Class Reference"里有如下介绍:
 
[plain]  
A SKStoreProductViewController object presents a store that allows the user to purchase other media from the App Store. For example, your app might display the store to allow the user to purchase another app.  
  
To display a store, create a new SKStoreProductViewController object and set its delegate. Then, present the view controller modally from another view controller in your app. Your delegate dismisses the view controller when the user completes the purchase.  
  
To choose a specific product, call the loadProductWithParameters:completionBlock: method, passing the iTunes item identifier for the item you want to sell.  
 
        由上可知,通过Modal view方式弹出App Store商品详情页面。我按照文档说明,写了个例子。部分代码如下:
[java]  
- (void)openAppWithIdentifier:(NSString *)appId {  
    SKStoreProductViewController *storeProductVC = [[SKStoreProductViewController alloc] init];  
    storeProductVC.delegate = self;  
      
    NSDictionary *dict = [NSDictionary dictionaryWithObject:appId forKey:SKStoreProductParameterITunesItemIdentifier];  
    [storeProductVC loadProductWithParameters:dict completionBlock:^(BOOL result, NSError *error) {  
        if (result) {  
            [self presentViewController:storeProductVC animated:YES completion:nil];  
        }  
    }];  
}  
 
另外,需要实现SKStoreProductViewControllerDelegate如下代理方法:
[java] 
#pragma mark - SKStoreProductViewControllerDelegate  
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {  
    [viewController dismissViewControllerAnimated:YES completion:^{  
        [viewController release];  
    }];  
}  
 
 
可以这样调用:
[java]  
[self openAppWithIdentifier:@"383037733"];  
 
这段代码即实现了上面图示的效果。
注:项目需要添加StoreKit框架,仅在iOS 6.0以上的设备中支持上述实现。
 
[java]  
Framework     
/System/Library/Frameworks/StoreKit.framework  
Availability      
Available in iOS 6.0 and later.  
 
如果需要兼容6.0以下的设备,可以使用下面的代码(这种方式会跳出当前应用):
 
[java] 
- (void)outerOpenAppWithIdentifier:(NSString *)appId {  
    NSString *urlStr = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/us/app/id%@?mt=8", appId];  
    NSURL *url = [NSURL URLWithString:urlStr];  
    [[UIApplication sharedApplication] openURL:url];  
}  

在Mac和iOS中注册自定义的URL Scheme


URL Scheme是类似http://ftp://afp://这样的东西,通常是用传输协议作为URL Scheme。不过事实上,你可以在iOS和Mac中注册任何类型的URL Scheme。当用户在浏览器中访问你的自定义URL Scheme的链接的时候,操作系统就会打开你的程序,响应这个请求。
要在程序中注册自定义URL Scheme非常简单。主要分为两个步骤:在程序的Info.plist中加入你需要注册的URL Scheme,然后在你的应用程序中加入处理这类请求的代码。
其中,第一个步骤对于iOS和Mac应用程序来说是完全相同的。方法如下:
Info.plist中,增加一个字段,名称为CFBundleURLTypes(URL Types)。Xcode会自动为你创建一个必须的键:URL Identifier(CFBundleURLName),这个键的值可以赋值为一个唯一的字符串。通常是逆向的域名结构,如:me.venj.myapp。然后在URL Types这个键下增加一个子项:CFBundleURLSchemes(URL Schemes),这里填入你想注册的URL Scheme的名称,如:cloud。你可以增加多个URL Scheme。
下面是一个示例的XML结构:
1
2
3
4
5
6
7
8
9
10
11
CFBundleURLTypes
CFBundleURLName me.venj.myapp CFBundleURLSchemes cloud
这样,我们就可以在程序中处理请求了。下面我们来分别看一下iOS和Mac下的处理方法:
iOS:
在iOS中,我们可以在AppDelegate中加入一个方法,来处理这个请求。对于iOS 4.1或更早的系统,使用-application:handleOpenURL:方法,对于iOS 4.2以后的系统使用:-application:openURL:sourceApplication:annotation:方法。
下面是示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* For iOS 4.1 and earlier */
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    // Handle url request.
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"URL Request" message:[url absoluteString] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];

    return YES;
}

/* For iOS 4.2 and later */
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    // Handle url request.
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"URL Request" message:[url absoluteString] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];

    return YES;
}
我们的演示程序只是简单的显示了一个UIAlertView来响应请求。实际应该如何处理那就看需要了。
效果如下:
Mac:
Mac下处理自定义URL Scheme的请求稍有不同。我们首先要在-applicationDidFinishLaunching:方法中注册一下,并指定处理URL请求的方法。如下:
1
2
3
4
5
6
7
8
9
10
11
12
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}

- (void)handleURLEvent:(NSAppleEventDescriptor*)theEvent withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
    // Process URL Request
    NSString* path = [[theEvent paramDescriptorForKeyword:keyDirectObject] stringValue];

    [[NSAlert alertWithMessageText:@"URL Request" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", path] runModal];
}
类似的,我们在示例程序中还是简单的用了一个NSAlert来展示我们成功捕获到了这个URL Scheme的请求。
效果如下:
好了,关于自定义URL Scheme就讲这么多,用起来很简单吧。